生产者消费者模型,C/C++实现(Linux)
来源:互联网 发布:mac 安装dmg到user 编辑:程序博客网 时间:2024/06/05 04:17
操作系统以及Linux上都详细地介绍了信号量以及锁的概念,其重要性可想而知,这事我写的一个比较简单的多线程实现的生产者消费者模型,我会对里面用到的函数等做出比较详细的解释,以方便解读。
#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <semaphore.h>#define PRODUCER 5 //生产者数目#define CONSUMER 5 //消费者数目#define POOL_SIZE 11 //缓冲池大小int pool[POOL_SIZE]; int head = 0; //第一个产品的位置int rear = 0; //最后一个产品的位置sem_t room_sem; //sem变量相当于,创建空余位置的信号量sem_t product_sem; //商品数目的信号量,和上面一个一起配合同步pthread_mutex_t mutex; //线程锁,控制互斥void *producer_fun() //生产者函数,注意他的返回类型{ while(1) { sleep(1); sem_wait(&room_sem); //申请一个空闲区域,相当于P pthread_mutex_lock(&mutex); //加锁,注意和P操作的顺序 pool[rear]=1; printf("producer:%d\n",rear); rear=(rear+1)%POOL_SIZE; pthread_mutex_unlock(&mutex);//解锁,和V操作顺序没有要求 sem_post(&product_sem);//释放一个商品变量,V操作,相当于加1 }}void *consumer_fun() //消费者函数,不解释了{ while(1) { sleep(2); sem_wait(&product_sem); pthread_mutex_lock(&mutex); int data=pool[head]; printf("consumer:%d\n",head); head=(head+1)%POOL_SIZE; pthread_mutex_unlock(&mutex); sem_post(&room_sem); }}int main(){ pthread_t producer_id[PRODUCER]; //保存生产者id的 pthread_t consumer_id[CONSUMER]; //保存消费者id pthread_mutex_init(&mutex,NULL); //初始化锁 int ret=sem_init(&room_sem,0,POOL_SIZE-1); //初始化信号量,为空闲区大小 if(ret!=0) { printf("room_sem init error\n"); exit(-1); } ret =sem_init(&product_sem,0,0); //初始化信号,为0 if(ret!=0) { printf("producer_sem init error\n"); exit(-1); } for(int i=0;i<PRODUCER;i++) //创建生产者线程 { ret = pthread_create(&producer_id[i],NULL,producer_fun,NULL); if(ret!=0) { printf("creat consumer pthread error!\n"); } } for(int i=0;i<CONSUMER;i++) //创建消费者线程 { ret = pthread_create(&consumer_id[i],NULL,consumer_fun,NULL); if(ret!=0) { printf("creat consumer pthread error!\n"); } } //释放线程资源 for(int i=0;i<PRODUCER;i++) { pthread_join(producer_id[i],NULL); } for(int i=0;i<CONSUMER;i++) { pthread_join(consumer_id[i],NULL); }}
上面代码除了我加的注释的地方外,别的需要说明的函数就两个
1、int pthread_create(pthread_t* tid, pthread_attr_t attr, void(start_routine)(void), void *arg);
tid:输出参数,用于返回所创建线程的标识;
attr:用于设定线程属性,大多数情况下传NULL;
start_routine:用于指定线程主函数
arg:为线程主函数传递的参数
我们看下这个函数的最后两个参数
void*(start_routine)(void):这个表示返回类型为void*,参数为void*的函数指针,如果城建的函数是其他类型,需要通过强制类型转化。
void arg:这是个传入的参数,但他最终不是传给pthread_create()。而是传给上面提到的那个绑定的void(start_routine)(void)。如果是其他类型的数据需要经过两次转化,如果需要多个参数可以通过结构体之类的数据结构包装。
2、int pthread_join(pthread_t tid, void **retval);
tid: 被等待的线程的id;
retval:出参,用于接收被等待线程结束时的返回值。
很多人可能对第二个参数比较奇怪,第二个参数相当于返回值,是一个出参,我们可以通过这个函数了解下:
int pthread_exit(void *retval);
retval: 线程结束时的返回值,用pthread_join可以获取该值。
这就比较好理解了。
为什么要回收线程退出状态呢,主要原因是linux有一种僵尸状态,在一个进程或者线程结束后,会有一个结构体,保存其退出是的状态等信息,只有在主线程回收以后他才会消失,当然,这里还有另外一种解决方式。
pthread_detach(pthread_self()) ;
他的作用是把该线程变为unjoinable,和主线程脱离关系,其在结束后会自动回收资源。
有讲的不对的地方希望指正,谢谢!!
- linux c pv 实现生产者消费者模型
- 生产者消费者模型,C/C++实现(Linux)
- 生产者与消费者模型Linux下C语言的实现
- linux c语言实现队列及用于生产者消费者模型
- Linux C:利用两个线程实现生产者消费者模型
- 生产者消费者---C实现
- Linux C 实现生产者消费者问题
- Linux实现生产者消费者模型
- 生产者消费者问题(C实现)
- [Linux]生产者与消费者 三种模型 C
- [Linux]生产者与消费者 三种模型 C
- c实现生产者消费者源代码
- C语言之生产者与消费者模型
- 生产者-消费者问题实现 (linux下C语言)
- 生产者-消费者问题实现 (linux下C语言)
- 生产者-消费者问题实现 (linux下C语言)
- C++编程实现生产者/消费者模型(linux系统编程)
- Linux 多线程编程(实现生产者消费者模型)
- CentOS安装gtk2.0
- RetroScope工具:Android设备内存取证
- 前端JS知识要点总结(6)
- ES6之Spread Operater拷贝对象
- CentOS7 设置redis重启配置文件
- 生产者消费者模型,C/C++实现(Linux)
- Android百度地图的使用
- 微信小程序---地图使用(定位/展示/周边信息展示/poi搜索)
- varnishi
- 表格可以横竖向滑动
- 笨方法学python(本文为阅读时从此书摘录的笔记) 第六天(留坑)
- java编程语言基础知识点(2)
- 简单查看服务器状态,不用登陆远程桌面
- poj-2395 Out of Hay