linux线程7(manufacturer and consumer)

问题描述:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。

首先假设简单的情况,生产者和消费者只有一个,且缓冲区也只有一个,这样就简单多了。

第一:从缓冲区取走产品和向缓冲区中投放产品必须是互斥的。可以用一个互斥锁来实现。

第二:生产者要等到缓冲区为空时才能投放产品,消费者要等缓冲区不为空时才能取走产品。由于有两个等待过程,所以可以加上两个条件变量来辅助互斥锁。

#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);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值