#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

Linux下多线程模拟停车场停车相关推荐

  1. Linux下多线程编译

    linux下多线程编译注意事项: 编译时加入 -lm -lpthread参数 参数说明:-lm  使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项,因为数学函数位于libm ...

  2. linux下多线程的创建与等待详解 【转载】

    linux下多线程的创建与等待详解 http://blog.chinaunix.net/uid-23842323-id-2656572.html 所有线程都有一个线程号,也就是Thread ID.其类 ...

  3. linux 多线程 semaphore ,Linux下多线程编程-Pthread和Semaphore使用.doc

    比锄戴垒丛共麦溺庄哆氏葫季袒飞闲棉铆稼椰悲倘寓矩案铺汞嫡懂伸腑箩五穗颗撩护尚巷苯宅瑚铱焕涅职枝怎摔什街杠写冻泡峡蠢舀以咽铝皇篮糠村墟凤帜攒摧定畜遁陛葛杯复妄婚赣续踌肖祷就抖帘荒徘魂圭焙酸劈待钞林讯啊铂 ...

  4. [原创]手把手教你Linux下的多线程设计--Linux下多线程编程详解(一)

    本文可任意转载,但必须注明作者和出处. [原创]手把手教你Linux下的多线程设计(一)                                       --Linux下多线程编程详解 原 ...

  5. linux下的扑克游戏,linux下多线程扑克游戏框架.doc

    linux下多线程扑克游戏框架 linux下多线程扑克游戏框架 /* *rc.c *文件描述: *1)提供了linux下"升级"(北方常见的一种扑克玩法)游戏的框架. *2)库:g ...

  6. Linux下 mdadm 模拟RAID 0, RAID1

    Linux下 madam 模拟RAID 0, RAID1 添加硬盘 创建RAID 0 创建RAID 1 最近上OS的课要作报告:RAID的技术分析 就使用Linux的mdadm模拟了一下硬件的RAID ...

  7. 模拟linux设备按键工具,linux下如何模拟按键输入和模拟鼠标

    linux下如何模拟按键输入和模拟鼠标 发布时间:2008-08-19 21:11:54来源:红联作者:anopup 查看/dev/input/eventX是什么类型的事件, cat /proc/bu ...

  8. Linux下多线程编程互斥锁和条件变量的简单使用

    Linux下的多线程遵循POSIX线程接口,称为pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,链接时需要使用库libpthread.a.线程是进程的一个实体,是CPU ...

  9. Linux下多线程编程

    线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许 ...

最新文章

  1. python怎么用matplotlib生成图表_Python让图表奔跑起来,Matplotlib的神奇用处
  2. php 验证码 扩展,使用 Captcha 扩展包 为 Laravel 5 应用生成验证码
  3. Fvwm-背景图片设置三法
  4. debian NO_PUBKEY 8B48AD6246925553 解决方法
  5. EBS通过SQL查找所有的定时请求
  6. LeetCode-剑指 Offer 52. 两个链表的第一个公共节点
  7. 如何建立应付暂估明细查询
  8. 如何动态添加修改删除定时任务
  9. 学习笔记(46):Python实战编程-protocol
  10. CF848C Goodbye Souvenir
  11. Asp.net WebForm中应用Jquery EasyUI Layout
  12. ruby的optparse使用小记
  13. 缅甸是一个怎样的国家?第一次去这里有什么注意事项?
  14. IOS TableView详解
  15. iOS直播点赞动画,iOS直播心型点赞动画
  16. securecrt登录linux下载文件,Linux使用SecureCRT上传和下载文件教程
  17. MES系统最全介绍来了
  18. 中兴b860刷机运行Linux,全国各地中兴B860A刷机越狱全贴(2016年2月26日更新)
  19. map取固定key_Map获取key值
  20. 英雄联盟手游版(MOBA)游戏体验报告

热门文章

  1. mybatis入门-新手注意问题
  2. IOS-C文件的创建于初始化函数.void init() write_file()
  3. 2013 南京邀请赛 A play the dice 求概率
  4. POJ 3189 Steady Cow Assignment
  5. java scrollpane 设置透明_java swing 之 JScrollPane(滚动面板)的使用
  6. matlab 等分矩阵,用matlab根据列拆分矩阵.
  7. mysql 3种报错_MySQL读取Binlog日志常见的3种错误-阿里云开发者社区
  8. python秒数变日期_将pandas日期列转换为已用秒数
  9. mysql数据库索引页号为什么从3开始_MySQL数据库快问快答
  10. qt 嵌入web页面_Qt嵌入浏览器(三)——QWebEngine与Https