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 4 typedef 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 = ;
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();
} 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()
{
//将线程挂起一段时间,模拟车辆到来的随机性
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 == )
{
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 != )
{
printf("Usage :%s carparksize\n",argv[]);
exit();
} cp_t outpark; initialise(&outpark,atoi(argv[])); //初始化停车场数据结构 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 ;
}
Linux下多线程模拟停车场停车的更多相关文章
- [转载]解决linux 下多线程错误 undefined reference to `sem_init'
转自:https://blog.csdn.net/yzycqu/article/details/7396498?utm_source=copy 解决linux 下多线程错误 undefined ref ...
- Linux下多线程下载工具 - Axel
Axel 是 Linux 下一个不错的HTTP/FTP高速下载工具.支持多线程下载.断点续传,且可以从多个地址或者从一个地址的多个连接来下载同一个文件.适合网速不给力时多线程下载提高下载速度.比如在国 ...
- Linux下多线程编程
一.为什么要引入线程? 使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式.在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维 ...
- Axel linux下多线程下载工具
Axel 是 Linux 下一个不错的HTTP/FTP高速下载工具.支持多线程下载.断点续传,且可以从多个地址或者从一个地址的多个连接来下载同一个文件.适合网速不给力时多线程下载提高下载速度.比如在国 ...
- Linux下多线程下载工具myget
[root@superdba ~]# mytgetMytget 0.0.99: A download accelerator for GNU/LinuxUsage: mytget [options]. ...
- linux下多线程断点下载工具-axel
今天要下载一下14G左右的文件,用wget约10小时,后来发现linux下有个多线程支持断点续传的下载工具axel,试了一下,下载速度大大增加. 包地址:http://pkgs.repoforge.o ...
- Linux下多线程复制文件(C)
Linux下实现多线程文件复制,使用<pthread.h>提供的函数: int pthread_create(pthread_t *thread,const pthread_attr_t ...
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
生产者消费者问题,又有界缓冲区问题.两个进程共享一个一个公共的固定大小的缓冲区.其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取信息. 问题的关键在于缓冲区已满,而此时生产者还想往其中 ...
- Linux下多线程编程遇到的一些问题
今天在学习了Linux的多线程编程的基础的知识点.于是就试着做了一个简单的Demo.本以为会得到预期的结果.不成想却遇到了意想不到的问题. 代码展示 我的C 代码很简单,就是一个简单的示例程序,如下: ...
随机推荐
- 自建Git服务Gogs和CI/CD服务Drone
自建Git服务Gogs和CI/CD服务Drone 项目:https://gogs.io Gogs运行 docker run -d --name=gogs -p 10022:22 -p 10088:30 ...
- android使用http3
http3的github地址: https://github.com/cloudflare/quiche
- 使用jQuery开发messager消息框插件
1.插件使用 首先引入jquery库,然后引入dialog.js.dialog.css.messager.js.messager.css,如下: <script type="text/ ...
- 数据结构与算法(周测7-拓扑排序和AOV网络)
判断题 1.AOE图的关键路径就是最长的路径 T F 2.AOE图的权值最大的边(活动)一定是关键活动. T F 两条边相加可能比最大的边还要大. 3.在AOE ...
- iOS - 静态库的导入和头文件路径的设置
开发过程中,免不了要用到一些第三方或者是别人写好的一些Demo,这时就经常会用到别人写的一些静态库(.a文件)和n多个头文件(.h文件),这些文件不是简单地把它们拉到自己的工程里面就行的,还要设置一些 ...
- node作为前台的项目如何打包静态js和css并生成版本号,loader插件的使用
一.使用场景: 1.node创建的前台项目需要输入地址展示页面 2.有设置缓存或者cdn的需要在静态文件更改时能使用新的而不是缓存的,需要版本号这里 3.可能需要压缩静态文件的 二.一些参考地址,需要 ...
- 超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用)
超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用) 转载自:https://www.jianshu.com/p/2ad8c8b5bf75 亲测有效~ <tem ...
- C#验证邮箱,电话,手机,数字,英文,日期,身份证,邮编,网址,IP类等常用函数封装
#region 验证邮箱验证邮箱 /**//// <summary> /// 验证邮箱 /// </summary> /// <param name="sour ...
- git/github安装与使用教程
新学习了Git和GitHub的使用,记一下笔记,也希望可以帮助他人,这里只是初级阶段,以后还会不断的修改和完善. 1.什么是git 开源的分布式版本控制系统,与svn比独特的地方: 1.解决了svn后 ...
- requests-html模块(下)
render方法 我们先理一下关系requests和的作者是同一个人,pyppeteer是nodejs中puppeteer的非官方实现 requests-html调用的pyppeteer与浏览器进行交 ...