Linux下多线程模拟停车场停车

 

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>#define ONE_SECOND 1000000
#define RANGE 10
#define PERIOD 2
#define NUM_THREADS 4typedef struct 
{int *carpark;    //用一个数组来模拟停车场停车位int capacity;    //停车场的车辆容量int occupied;    //停车场现有的车辆数目int nextin;        //下一个进来的车的位置(用carpark数组代表的下标表示)int nextout;    //下一个取走的车的停车位置int cars_in;    //记录停车场进入车辆的总和int cars_out;    //记录从停车场开出去的车辆总和pthread_mutex_t lock;    //互斥量,保护该结构中的数据被线程互斥的方式使用pthread_cond_t space;    //条件变量    描述停车场是否有空位置pthread_cond_t car;        //条件变量    描述停车场是否有车pthread_barrier_t bar;    //线程屏障
}cp_t;static void initialise(cp_t *cp,int size)
{cp->occupied = cp->nextin = cp->nextout = cp->cars_in = cp->cars_out = 0;cp->capacity = size;cp->carpark = (int *)malloc(cp->capacity * sizeof(*cp->carpark));//初始化线程屏障,NUM_THREADS表示等待 NUM_THREADS=4个线程同步执行pthread_barrier_init(&cp->bar,NULL,NUM_THREADS);if(cp->carpark == NULL){perror("malloc()");exit(1);}srand((unsigned int )getpid());pthread_mutex_init(&cp->lock,NULL);     //初始化停车场的锁pthread_cond_init(&cp->space,NULL);        //初始化描述停车场是否有空位的条件变量pthread_cond_init(&cp->car,NULL);        //初始化描述停车场是否有车的条件变量
}static void* car_in_handler(void* carpark_in)
{cp_t *temp;unsigned int seed;temp = (cp_t *)carpark_in;//pthread_barrier_wait 函数表示,线程已完成工作,等到其他线程赶来pthread_barrier_wait(&temp->bar);while(1){//将线程挂起一段时间,模拟车辆到来的随机性usleep(rand_r(&seed) % ONE_SECOND);pthread_mutex_lock(&temp->lock);//循环等待知道有停车位while(temp->occupied == temp->capacity)pthread_cond_wait(&temp->space,&temp->lock);//插入一辆车,用随机数标识temp->carpark[temp->nextin] = rand_r(&seed) % RANGE;temp->occupied++;temp->nextin++;temp->nextin %= temp->capacity;temp->cars_in++;//可能有的人在等车可取,发送temp->car条件变量pthread_cond_signal(&temp->car);pthread_mutex_unlock(&temp->lock);}return ((void*)NULL);
}static void* car_out_handler(void *carpark_out)
{cp_t *temp;unsigned int seed;temp = (cp_t *)carpark_out;pthread_barrier_wait(&temp->bar);for(;;){usleep(rand_r(&seed) % ONE_SECOND);pthread_mutex_lock(&temp->lock);/*获得锁后访问temp->occupied 变量,此时如果车辆数为0 (occupied == 0)pthread_cond_wait 进行的操作就是忙等,释放锁(&temp->lock)供其他路线使用知道temp->car条件改变时再次将锁锁住*/while(temp->occupied == 0){pthread_cond_wait(&temp->car,&temp->lock);}temp->occupied--;temp->nextout++;temp->nextout %= temp->capacity;temp->cars_out++;pthread_cond_signal(&temp->space);pthread_mutex_unlock(&temp->lock);}return ((void *)NULL);
}static void *monitor(void *carpark_in)
{cp_t *temp;temp = (cp_t *)carpark_in;for(;;){sleep(PERIOD);pthread_mutex_lock(&temp->lock);printf("Delta:%d\n",temp->cars_in - temp->cars_out - temp->occupied);printf("Number of cars in carpark:%d\n",temp->occupied);pthread_mutex_unlock(&temp->lock);}return ((void *)NULL);
}int main(int argc,char **argv)
{printf("main version 1.0\n");if(argc != 2){printf("Usage :%s carparksize\n",argv[0]);exit(1);}cp_t outpark;initialise(&outpark,atoi(argv[1]));  //初始化停车场数据结构
pthread_t car_in,car_out,m;                //定义线程变量
    pthread_t car_in2,car_out2;/***创建往停车场停车线程(生成者1)创建从停车场取车线程(消费者1)创建往停车场停车线程(生成者2)创建从停车场取车线程(消费者2)创建用于监控停车场状况的线程***/pthread_create(&car_in,NULL,car_in_handler,(void*)&outpark);pthread_create(&car_out,NULL,car_out_handler,(void*)&outpark);pthread_create(&car_in2,NULL,car_in_handler,(void*)&outpark);pthread_create(&car_out2,NULL,car_out_handler,(void*)&outpark);pthread_create(&m,NULL,monitor,(void*)&outpark);//pthread_join的第二个参数为NULL,表示不关心线程返回状态,仅仅等待指定线程的终止
    pthread_join(car_in,NULL);pthread_join(car_out,NULL);pthread_join(car_in2,NULL);pthread_join(car_out2,NULL);pthread_join(m,NULL);return 0;
}

 

转载于:https://www.cnblogs.com/wanghao-boke/p/11613071.html

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

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

相关文章

【C++学习之路】第一章——C++核心方法总论

1 C核心方法总论 1.1 核心思想 通过实际项目来学习编程&#xff0c;更高效掌握编程规则&#xff0c;以及明白各种语法规则的实际应用。 实验思想&#xff1a;任何C的参考资料都不可能覆盖你遇到的所有问题&#xff0c;这个时候&#xff0c;最好的办法就是&#xff0c;编辑代…

【Verilog HDL学习之路】第一章 Verilog HDL 数字设计总论

1 Verilog HDL 数字设计总论 1.1 几个重要的概念 EDA&#xff08;Electronic Design Automation&#xff09; 电子技术自动化 EDA工具 类似于软件工程中的IDE&#xff08;集成开发环境&#xff09;&#xff0c;能够使用Verilog HDL语言描述电路设计&#xff0c;并且能够通过逻…

【学会如何学习系列】从婴儿到大学——学习的本质从未改变过

从婴儿到大学——学习的本质从未改变过 从我们出生一直到现在&#xff0c;其实&#xff0c;学习的本质从来都没有改变过&#xff0c;并且&#xff0c;婴儿时期的我们&#xff0c;是学习能力最强的时候&#xff0c;随着我们不断长大&#xff0c;外界的诱惑越来越多&#xff0c;…

【汇编语言学习之路】第一章 汇编语言核心方法论

版权声明&#xff1a;本学习笔记是本人根据小甲鱼“汇编语言学习课程”和《汇编语言》&#xff08;王爽&#xff09;的书籍&#xff0c;来记录笔记的 1 汇编语言核心方法论 1.1 学习汇编语言的必要性 汇编语言与机器语言是一一对应关系&#xff0c;它的本质是机器语言的代号。…

蓝桥单片机赛题及模拟题代码

链接&#xff1a;https://pan.baidu.com/s/1BVB6VILEed0ufqRDMhvALg 提取码&#xff1a;ukx7

【Verilog HDL学习之路】第二章 Verilog HDL的设计方法学——层次建模

2 Verilog HDL的设计方法学——层次建模 重要的思想&#xff1a; 在语文教学中&#xff0c;应该先掌握核心方法论&#xff0c;再用正确的方法论去做题目&#xff0c;这样能够逐渐加深对于方法论的理解&#xff0c;做题的速度和准确率也会越来越高。在Verilog HDL中&#xff0c…

stm32机械臂资料含视频

这是在网上买的机械臂的资料 含视频及相关软件 在这里分享给大家 不过很大 但是内容很全 链接&#xff1a;https://pan.baidu.com/s/1Fd18ww8jxLH8ChqomstZtw 提取码&#xff1a;147g

【Verilog HDL】第四章 模块的端口连接规则——污水处理模型

先放上连接规则的简图&#xff0c;再详细解释 1. 构建模型——污水处理之流水模型 我们先将上述结构构件一个简单模型&#xff0c;以帮助我们理解。 污水&#xff1a;输入数据净水&#xff1a;输出数据双向数据暂不讨论&#xff0c;取输入和输出的交集即可污水处理厂&…

蓝桥杯嵌入式第七届模拟题 代码

链接&#xff1a;https://pan.baidu.com/s/1fdGC20A51axxPGpoyRL8-w 提取码&#xff1a;by4u

三级嵌入式选择知识点整理

SoC芯片 通用SoC是系统级芯片 既可以是单核 也可以是多核 该芯片中可以包含数字电路 模拟电路 数字模拟混合电路 及射频电路 片上系统可使用单个芯片进行数据的采集 转换 储存 处理 及I/O口功能 智能手机 和平板都使用的SOC WAV是未压缩的数字音频 音质与CD相当 音频视频压缩…

【Verilog HDL】命名的规则研究

Verilog命名规范参考资料 1. 什么可以被命名&#xff1f; 模块的名称模块实例的名称各种数据类型的名称 这些名称我们称之为标识符&#xff0c;标识符的命名规则不再强调&#xff0c;与C语言类似&#xff0c;字母、数字、下划线&#xff08;_&#xff09;和美元符号&#xf…

【Verilog HDL】深入理解部分语法规则的本质

1. 门级描述 统一规则&#xff1a; 门类型 (输出&#xff0c;输入); 细化规则&#xff1a; 与/或门&#xff1a; 多入一出 门 (输出&#xff0c;输入1&#xff0c;输入2,……);缓冲门/非门&#xff1a;一入多出 门 (输出1&#xff0c;输出2,……输出n&#xff0c;输入); 门…

三级嵌入式填空整理

实时 可预测性是实时系统的重要性能标准 按照响应时间 实时操作系统可分为 1.普通实时操作系统 响应时间一般是秒级 2.强实时操作系统 响应时间为毫秒和微秒级 3.弱实时操作系统 响应时间为数十秒 RTOS 响应中断请求并完成相应中断服务子程序的时间非常快 这个时间具有一致性…

【Verilog HDL】从逻辑电路图到门级建模——人工翻译的方法论

从左到右&#xff0c;从上到下 先搞定缓冲/非门&#xff0c;再写与/或门 1. 实例解读 先以四选一数据选择器进行说明 对于数字逻辑的部分不再说明&#xff0c;直接进行逻辑电路图到Verilog门级建模的人工翻译过程的描述。 1.1 端口和线网分析 确定输入/输出端口 输入端口 …

三级嵌入式 汇编指令汇总

ARM条件码 EQ 相等 NE 不相等 CS/HS 无符号大于等于 CC/LO 无符号小于 HI 无符号大于 LS 无符号小于等于 GE 带符号大于等于 L…

【Verilog HDL】语句的并发执行

1. 实践得到的启发 先从一个简单的现象得出结论&#xff0c;Verilog语句是并发执行的&#xff01; 同时&#xff0c;这也是**$monitor系统任务为全局有效**的一个重要支持因素&#xff0c;如果没有并发&#xff0c;它是完不成这项功能的实现的。 众所周知&#xff0c;高级语…

linux下 最常用基本命令

常用命令 基本命令 pwd 打印绝对路径 ls 路径 列举文件名 ls 列举文件的权限 属于哪个用户 容量大小 修改…

【数字逻辑】第四章 组合逻辑电路:端口设计 端口拓展的方法

1. 端口设计的方法 1.1 数据选择器 以四选一数据选择器为例&#xff0c;需要的不同接口类型为 输入端口 数据输入端口地址输入端口使能端&#xff08;控制与拓展&#xff09; 输出端口 数据输出端口 2. 端口拓展的方法——层次建模思想 2.0 两个拓展方向 2.0.1 “数组型…

GCC及Makefile基本使用教程

GCC .c c原始程序 .C/.cc/.cxx c原始程序 .m objective-C原始程序 .i 已经预处理过的c原始程序 .ii 已经预处理过的c原始程序 .s/.S 汇编原始程序 .h 预处理头文件 .o 目标文件 .a/.so 编译后的库文件 -E 生成预处理文件 -S 生成编译过的汇编文件 -c 目标文件 .o -o…

【Verilog HDL】第三章 reg和net及其一组类型的区别——充分运用实验思维

0 确定问题的讨论层级与范围 本文讨论的层次是 数字逻辑与Verilog HDL语言 讨论的范围是&#xff1a; 数据存储而不是讨论逻辑 1 线网类型 1.1 wire类型 这个暂时没什么好说的&#xff0c;一般常用的就是wire类型&#xff0c;需要注意的是&#xff1a; 默认是标量&…