Linux 操作系统原理作业 - 行人与机动车问题

news2025/1/18 11:02:05

大三上学期操作系统原理这门课中,老师给了一道作业《行人与机动车问题》;

即Linux多线程下处理行人与机动车谁优先的问题,需要用到多线程和互斥量;


行人 - 机动 车问题

假设有一个路口,有很多行人和机动车需要通过,通行交通规则如下:允许多个行人同时通过这个路口,但在任何时候如果有一辆机动车通过,那既不允许行人通过,也不允许其他机动车通过。

在此交通规则下,有2种同步互斥过程,一种是行人优先,即只有没有行人在通过路口且没有其他机动车在通过路口时该机动车才能通过;另一种是机动车优先,如果一个行人申请通过时已有另一辆机动车在等待通过路口,则该行人必须等到没有机动车处于等待状态后才能开始通过。

现在给出行人优先模式的实现过程,模拟效果如下:

输入说明:

每4个字符为一组,代表一次通过,每组第一个字符表示编号,从1开始,逐次递增1;第二字符表示通过类型,W表示行人通过,V表示机动车通过;第三个字符表示到达路口需要的时间;第四个字符表示通过路口需要的时间。

行人优先代码

# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/types.h>
# include <pthread.h>
# include <string.h>
# include <unistd.h>
//定义互斥锁
//mutex1用于实现walkmanCount的互斥访问
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//mutex2用于实现行人和机动车,机动车之间的互斥通过路口
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
int walkmanCount; //行人数量


struct data {
	int id; //编号
	int opTime;//到达路口的时间
	int lastTime;//通过路口需要的时间
};


void* Walkman(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime); //模拟走到路口的过程,沉睡时间等于走到路口的时间
	printf("Thread %d: waiting to walk\n", id);	
	
	pthread_mutex_lock(&mutex1);
	walkmanCount++;
	if(walkmanCount == 1)
		pthread_mutex_lock(&mutex2);
	pthread_mutex_unlock(&mutex1);
	
	printf("Thread %d: start walking\n", id);
	
	sleep(lastTime);//模拟通过的过程,沉睡的时间等于通过的时间
	printf("Thread %d: end walking\n", id);

	pthread_mutex_lock(&mutex1);
	walkmanCount--;
	if(walkmanCount == 0)
		pthread_mutex_unlock(&mutex2);
	pthread_mutex_unlock(&mutex1);

	pthread_exit(0);//线程退出一定要有,不然就会成为僵尸线程
}


void* Vehicle(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime);//模拟机动车走到路口的过程
	printf("Thread %d: waiting to drive\n", id);
	
	pthread_mutex_lock(&mutex2);
	printf("Thread %d: start driving\n", id);
	sleep(lastTime);//模拟机动车通过的过程
	printf("Thread %d: end driving\n", id);
	
	pthread_mutex_unlock(&mutex2);
	
	pthread_exit(0);//线程退出
}

int main() {
	pthread_t tid; // the thread identifier

	pthread_attr_t attr; //set of thread attributes

	pthread_attr_init(&attr);

        walkmanCount = 0;

	int id = 0;
	while(scanf("%d", &id) != EOF) {

		char role;		
		int opTime;		
		int lastTime;	

		scanf("%c%d%d", &role, &opTime, &lastTime);
		struct data* d = (struct data*)malloc(sizeof(struct data));

		d->id = id;
		d->opTime = opTime;
		d->lastTime = lastTime;

		if(role == 'W') {
			printf("Create the %d thread: Walkman\n", id);
			pthread_create(&tid, &attr, Walkman, d);

		}
		if(role == 'V') {
			printf("Create the %d thread: Vehicle\n", id);
			pthread_create(&tid, &attr, Vehicle, d);
		}
	}
	
	pthread_mutex_destroy(&mutex1);
	pthread_mutex_destroy(&mutex2);

	return 0;
}

任务:实现机动车优先模式,即如果一个行人申请通过路口时已有另一机动车在等待通过,则该行人必须等到没有机动车处于等待状态后才能通过路口,实现效果如下:


机动车优先代码实现

使用上面行人优先的代码,改为机动车优先的代码! 

# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/types.h>
# include <pthread.h>
# include <string.h>
# include <unistd.h>


//定义互斥锁
//mutex1用于实现行人的互斥访问
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//mutex2用于实现行人和机动车,机动车之间的互斥通过路口
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
// 辅助互斥
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;

int walkmanCount; 	// 行人数量
int vehicleCount;	// 机动车数量

struct data {
	int id; //编号
	int opTime;//到达路口的时间
	int lastTime;//通过路口需要的时间
};


void* Walkman(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime); //模拟走到路口的过程,沉睡时间等于走到路口的时间
	printf("Thread %d: waiting to walk\n", id);	
	
	pthread_mutex_lock(&mutex1);
	walkmanCount++;
	if (walkmanCount == 1) {
		pthread_mutex_lock(&mutex2);
	}
	pthread_mutex_unlock(&mutex1);

	printf("Thread %d: start walking\n", id);	
	
	
	sleep(lastTime);//模拟通过的过程,沉睡的时间等于通过的时间
	printf("Thread %d: end walking\n", id);

	pthread_mutex_lock(&mutex3);
	walkmanCount--;
	if (walkmanCount == 0) {
		pthread_mutex_unlock(&mutex2);
	}
	pthread_mutex_unlock(&mutex3);

	pthread_exit(0);//线程退出一定要有,不然就会成为僵尸线程
}


void* Vehicle(void* param) {
	int id = ((struct data*)param)->id;
	int lastTime = ((struct data*)param)->lastTime;
	int opTime = ((struct data*)param)->opTime;

	sleep(opTime);//模拟机动车走到路口的过程
	printf("Thread %d: waiting to drive\n", id);
	
	pthread_mutex_lock(&mutex3);
	if (0 == vehicleCount) {
		// 有多辆机动车等待时,只锁mutex1一次
		pthread_mutex_lock(&mutex1);
	}
	vehicleCount++;
	pthread_mutex_unlock(&mutex3);
	
	
	pthread_mutex_lock(&mutex2);
	printf("Thread %d: start driving\n", id);

	sleep(lastTime);//模拟机动车通过的过程
	printf("Thread %d: end driving\n", id);

	vehicleCount--;
	if (0 == vehicleCount) {
		// 机动车没有等待了,解除mutex1的锁
		pthread_mutex_unlock(&mutex1);
	}
	pthread_mutex_unlock(&mutex2);
	
	pthread_exit(0);//线程退出
}

int main() {
	pthread_t tid; // the thread identifier

    walkmanCount = 0;
    vehicleCount = 0;
    
    pthread_mutex_init(&mutex1, 0);
    pthread_mutex_init(&mutex2, 0);
    pthread_mutex_init(&mutex3, 0);

	int id = 0;
	while(scanf("%d", &id) != EOF) {

		char role;		
		int opTime;		
		int lastTime;	

		scanf("%c%d%d", &role, &opTime, &lastTime);
		struct data* d = (struct data*)malloc(sizeof(struct data));

		d->id = id;
		d->opTime = opTime;
		d->lastTime = lastTime;

		if(role == 'W') {
			printf("Create the %d thread: Walkman\n", id);
			pthread_create(&tid, 0, Walkman, d);

		}
		if(role == 'V') {
			printf("Create the %d thread: Vehicle\n", id);
			pthread_create(&tid, 0, Vehicle, d);
		}
	}
	
	pthread_mutex_destroy(&mutex1);
	pthread_mutex_destroy(&mutex2);
	pthread_mutex_destroy(&mutex3);

	return 0;
}

测试案例: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1673_MIT 6.828 Homework xv6 lazy page allocation要求翻译

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 在计划表中看到了这样一份作业&#xff0c;做一个简单的翻译整理。原来的页面&#xff1a;Homework: xv6 lazy page allocation (mit.edu) 家庭作业&#xff1a;x…

代码版本M、RC、GA、Release等标识的区别

引言 最近听说spring framework有了重大版本调整&#xff0c;出了6.0的GA版本了 那GA是啥意思呢&#xff1f; 看了下spring 官网和代码仓库&#xff0c;除了GA&#xff0c;还有M、RC、Release等 Spring FrameworkLevel up your Java code and explore what Spring can do f…

[Java Web]element | 一个由饿了么公司开发的前端框架,让你快速构建现代化、美观的 Web 应用程序。

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Java Web ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&a…

【mybatis】mybatis的工作原理

目录一、工作流程二、说明2.1 构建SqlSessionFactory2.2 SqlSession的获取2.3 SqlSession执行语句三、源码结构3.1 接口层3.2 核心处理3.3 核心处理层四、代码示例4.1 通过inputStream构建SqlSessionFactory4.2 通过configuration构建SqlSessionFactory4.3 mybatis-config.xml示…

groovy环境搭建

什么是DSL? 领域特定语言DSL&#xff08;全称&#xff1a;domain specific language&#xff09; 常见的DSL语言有&#xff1a;UML、HTML、SQL、XML、Groovy 作用&#xff1a;解决某一特定领域的问题 什么是groovy? groovy是一种基于JVM的敏捷开发语言。 结合了Python、Ruby和…

Vite4+Vuejs3项目初步搭建,并部署多个vue项目到nginx

前提条件 1、熟悉命令行 2、已安装 16.0 或更高版本的 Node.js 参照vuejs官网的步骤&#xff0c;创建一个vue前端项目 当前vuejs的版本&#xff1a;3.2.47 npm init vuelatestVue.js - The Progressive JavaScript Framework√ Project name: ... vuejs3-project√ Add Type…

BitDock桌面美化工具 一直在后台偷偷上传东西,具体上传什么东西不知,一天耗费我几十个G的流量

通过流量防火墙监控发现bitdock一直在上传东西&#xff0c;目前截止发现已上传了40G的流量 ――――――――――――――――――――――― 程序名称&#xff1a;SystemAudioDetection.exe 程序说明&#xff1a; 路径&#xff1a;D:\BitDock\AudioEngine\SystemAudioDetecti…

【C 字符串】02 字符串函数(命令行参数)

Navigator一、strlen()函数—统计长度二、strcat()函数—拼接三、strncat()函数—strcat()的升级四、strcmp()和strncmp()—比较五、strcpy()和strncpy()—拷贝六、sprintf()函数—合并多个字符串七、其他可能用到的字符串函数八、ctype.h中的字符函数九、把字符串转换为数字十…

在线文章生成工具-原创文章生成工具

在线文章生成器 在线文章生成器是指一种可以在线使用的自动化创造文章的工具。它可以使用自然语言处理&#xff08;NLP&#xff09;技术和人工智能算法提供需要的信息&#xff0c;基于标题、关键字&#xff0c;句子关联性等元素自动创造文章内容&#xff0c;涵盖各种类型&…

双端队列 码蹄集

题目来源&#xff1a;码蹄集 题目描述&#xff1a; 题意分析&#xff1a; 这道题目需要使用到双端队列的数据结构。我们可以借助 STL 中的 deque 来实现这个数据结构。具体来说&#xff0c;我们可以通过 deque 的 push_front 和 push_back 操作在队列的头部和尾部添加元素&am…

地球系统模式(CESM)实践技术应用

目前通用地球系统模式&#xff08;Community Earth System Model&#xff0c;CESM&#xff09;在研究地球的过去、现在和未来的气候状况中具有越来越普遍的应用。于2010年07月推出以来&#xff0c;一直受到气候学界的密切关注。近年升级的CESM2.0在大气、陆地、海洋、海冰、陆冰…

图形库EasyX的学习:)

最近学了一点做小游戏的基本知识&#xff0c;来总结一下&#xff0c;巩固一下记忆&#xff1a; 在这个基础上初学者要先明白vs的下载及基本使用还有图形库的下载及安装&#xff1b; 然后才是正题&#xff1a; 图形库里包含c语法&#xff0c;所以要用c文件&#xff0c;但是除…

Ubantu docker学习笔记(六)容器数据卷——补充实验

文章目录一、volume container二、 data-packed volume container三、利用数据卷驱动共享数据注意要在同一个网络配置下&#xff01;3.1服务端3.2客户端一、volume container 这里我觉得很好理解&#xff0c;volume container是专门为其他容器提供volume的容器。其实也就相当于…

深圳海运到墨西哥需要多长时间

目前&#xff0c;墨西哥的跨境电商商业正在高速发展&#xff0c;并且具有可观的红利。因此&#xff0c;从中国到墨西哥的运输需求很大&#xff0c;特别是海运&#xff0c;是很多跨境电商卖家主要选择的运输方式。 一般而言&#xff0c;中国到墨西哥的跨境卖家们普遍关注海运所需…

“终于我从字节离职了...“一个年薪40W的测试工程师的自白...

”我递上了我的辞职信&#xff0c;不是因为公司给的不多&#xff0c;也不是因为公司待我不好&#xff0c;但是我觉得&#xff0c;我每天看中我憔悴的面容&#xff0c;每天晚上拖着疲惫的身体躺在床上&#xff0c;我都不知道人生的意义&#xff0c;是赚钱吗&#xff1f;是为了更…

【云原生进阶之容器】第五章容器运行时5.8--容器热迁移

《云原生进阶之容器》专题索引: 第一章Docker核心技术1.1节——Docker综述第一章Docker核心技术1.2节——Linux容器LXC第一章Docker核心技术1.3节——命名空间Namespace第一章Docker核心技术1.4节——chroot技术第一章Docker核心技术1.5.1节——cgroup综述

MySQL-存储过程

什么是存储过程我们前面所学习的MySQL语句都是针对一个表或几个表的单条 SQL 语句&#xff0c;但是在数据库的实际操作中&#xff0c;并非所有操作都那么简单&#xff0c;经常会有一个完整的操作需要多条SQL语句处理多个表才能完成。例如&#xff0c;为了确认学生能否毕业&…

015 - C++ 类与结构体对比

今天这期我们主要解决一个问题&#xff0c;就是 C 中的类和结构体有什么区别。 上一期我们讲类的时候&#xff0c; 我们对类有了一些基本的介绍&#xff0c;在本期的学习开始之前你可以先看看那一期。 本期我们有两个术语&#xff0c;结构体 struct&#xff0c;它是 structur…

【终结扩散模型】Consistency Models.OpenAI开源新模型代码,一步成图,1秒18张

【终结扩散模型】Consistency Models.OpenAI开源新模型代码&#xff0c;一步成图&#xff0c;1秒18张0、前言Abstract1. Introduction2. Diffusion Models3. Consistency Models3.1 Definition3.2 Parameterization3.3 Sampling3.4 Zero-Shot Data Editing4. Training Consiste…

MySQL运维13-数据库性能测试

文章目录1、数据库性能指标1.1、事务吞吐率1.2、响应时间2、数据库性能测试的目的3、数据库性能测试的注意事项4、数据库性能测试工具选型4.1、sysbench4.2、mysqlslap5、sysbench测试介绍5.1、sysbench的安装5.1.1、sysbench的正常安装步骤5.1.2、安装中的异常处理5.2、sysben…