linux线程7(manufacturer and consumer)
2015-09-29 19:19
579 查看
问题描述:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。
首先假设简单的情况,生产者和消费者只有一个,且缓冲区也只有一个,这样就简单多了。
第一:从缓冲区取走产品和向缓冲区中投放产品必须是互斥的。可以用一个互斥锁来实现。
第二:生产者要等到缓冲区为空时才能投放产品,消费者要等缓冲区不为空时才能取走产品。由于有两个等待过程,所以可以加上两个条件变量来辅助互斥锁。
![](https://img-blog.csdn.net/20150929192050766?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
下面来看复杂点的情况:将消费者改成两个,缓冲池改为拥有4个缓冲区的大地址池。
如何分析这个问题?消费者数量变多,影响不大,只需增加对应线程的个数即可。唯一要注意的是缓冲池变大了。但是依然可以用缓冲池是否为空来判断是否可读缓冲池,,只不过写入缓冲池的条件变为非空缓冲池的个数不为0。
![](https://img-blog.csdn.net/20150929205741826?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
<
4000
/p>
首先假设简单的情况,生产者和消费者只有一个,且缓冲区也只有一个,这样就简单多了。
第一:从缓冲区取走产品和向缓冲区中投放产品必须是互斥的。可以用一个互斥锁来实现。
第二:生产者要等到缓冲区为空时才能投放产品,消费者要等缓冲区不为空时才能取走产品。由于有两个等待过程,所以可以加上两个条件变量来辅助互斥锁。
#include <iostream> #include <pthread.h> using namespace std; const int MAX=10; //需要生产的数量 int num=0; pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; //互斥量 pthread_cond_t condp=PTHREAD_COND_INITIALIZER,condc=PTHREAD_COND_INITIALIZER; //条件变量 int flag=0; //为0表示缓冲区没有产品,为1表示缓冲区有产品 void *producer(void *arg); //生产者 void *consumer(void *arg); //消费者 int main() { pthread_t tid1,tid2; //线程ID pthread_create(&tid1,NULL,producer,NULL); //生产者线程 pthread_create(&tid2,NULL,consumer,NULL); //消费者线程 pthread_join(tid1,NULL); pthread_join(tid2,NULL); return 0; } void *producer(void *arg) { for(int i=0;i<MAX;i++) { pthread_mutex_lock(&mutex); while(flag==1) pthread_cond_wait(&condp,&mutex); flag=1; cout<<"生产者生产第 "<<i+1<<" 个产品"<<endl; pthread_cond_signal(&condc); //唤醒消费者(重要) pthread_mutex_unlock(&mutex); } } void *consumer(void *arg) { for(int i=0;i<MAX;i++) { pthread_mutex_lock(&mutex); while(flag==0) pthread_cond_wait(&condc,&mutex); flag=0; cout<<"消费者消费第 "<<i+1<<" 个产品"<<endl; pthread_cond_signal(&condp); //唤醒消费者(重要) pthread_mutex_unlock(&mutex); } }
下面来看复杂点的情况:将消费者改成两个,缓冲池改为拥有4个缓冲区的大地址池。
如何分析这个问题?消费者数量变多,影响不大,只需增加对应线程的个数即可。唯一要注意的是缓冲池变大了。但是依然可以用缓冲池是否为空来判断是否可读缓冲池,,只不过写入缓冲池的条件变为非空缓冲池的个数不为0。
#include <iostream> #include <pthread.h> using namespace std; const int MAX=10; //需要生产的数量 int num=0; pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; //互斥量 pthread_cond_t condp=PTHREAD_COND_INITIALIZER,condc=PTHREAD_COND_INITIALIZER; //条件变量 int flag=0; //为0表示缓冲区没有产品,为1表示缓冲区有产品 void *producer(void *arg); //生产者 void *consumer(void *arg); //消费者 int main() { pthread_t tid1,tid2; //线程ID pthread_create(&tid1,NULL,producer,NULL); //生产者线程 pthread_create(&tid2,NULL,consumer,NULL); //消费者线程 pthread_join(tid1,NULL); pthread_join(tid2,NULL); return 0; } void *producer(void *arg) { for(int i=0;i<MAX;i++) { pthread_mutex_lock(&mutex); while(flag==1) pthread_cond_wait(&condp,&mutex); flag=1; cout<<"生产者生产第 "<<i+1<<" 个产品"<<endl; pthread_cond_signal(&condc); //唤醒消费者(重要) pthread_mutex_unlock(&mutex); } } void *consumer(void *arg) { for(int i=0;i<MAX;i++) { pthread_mutex_lock(&mutex); while(flag==0) pthread_cond_wait(&condc,&mutex); flag=0; cout<<"消费者消费第 "<<i+1<<" 个产品"<<endl; pthread_cond_signal(&condp); //唤醒消费者(重要) pthread_mutex_unlock(&mutex); } }
<
4000
/p>
相关文章推荐
- linux常用命令(62):watch命令
- Linux系统安装Python
- linux下xargs命令用法详解
- LINUX 用户管理
- mount挂载分区,和/etc/fstab开机自动挂载
- pread,pwrite,read,write区别
- C++进阶学习——线程基类的设计(Linux)
- CentOS6.6环境下布署LVS+keepalived
- CentOS安装Java
- linux常用命令(61):ps命令
- linux hosts.allow 只允许adsl动态ip登录
- linux常用命令(60):wc命令
- CentOS 6.6下的J2EE环境搭建(五)之MySQL安装
- Centos7 安装Cobbler
- linux常用命令(59):grep命令
- CentOS进程管理
- rz和sz 和他们的参数们
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本(转载)
- 【linux学习笔记七】关机重启命令
- Linux命令总结