生产者与消费者模型代码实现

18 篇文章 0 订阅

用一个队列创建一个仓库,生产线程往里加数据,而消费者在里面读。
如果仓库满了,消费者无法生产,如果仓库为0,消费者线程无法使用

#include <iostream>                                                                                             
  #include<pthread.h>
  #include<queue>
  #define MAX_Queue 10
  using namespace std ;
  class Blockqueue{  //生产者消费者队结构体 
    private:
      queue <int> _queue;  //用于放数据的队列
      pthread_cond_t _cond_product;//生产者条件变量
      pthread_cond_t _cond_consumer;//消费者条件变量
      pthread_mutex_t _mutex;//用于互斥的锁
      int _capacity;//队列容量 因为queue结构体可以无限扩容,如果没有容量限制可能导致资源耗尽程序崩溃
    public:
      Blockqueue(int cap = MAX_Queue):_capacity(cap){  //构造函数初始化数据
        pthread_cond_init(&_cond_product,NULL);
        pthread_cond_init(&_cond_consumer,NULL);
        pthread_mutex_init(&_mutex,NULL);
      }
      ~Blockqueue() {  //析构函数销毁条件变量 互斥锁
        pthread_cond_destroy(&_cond_product); 
        pthread_cond_destroy(&_cond_consumer);
        pthread_mutex_destroy(&_mutex);
      }
      bool QueuePush(int data)
      {    //在队列中放入元素 相当于生产 
           //进来先上锁,防止别人访问,互斥
        pthread_mutex_lock(&_mutex);
      while(_queue.size() == _capacity)//循环判断防止其他线程先于此线程唤醒从而引发错误
        {   //如果容量满了,将其加入到条件变量中 分三步 解锁 然后休眠 被唤醒后加锁
          pthread_cond_wait(&_cond_product,&_mutex);
        }//如果while循环结束那么意味着有容量于是插入
        _queue.push(data);
        pthread_mutex_unlock(&_mutex);//开锁
        pthread_cond_signal(&_cond_consumer);//唤醒消费者线程
    }  
    //消费者线程 原理同上只不过 条件不一样
      bool QueuePop(int &data){
        pthread_mutex_lock(&_mutex);
        while(_queue.size() == 0){
          pthread_cond_wait(&_cond_consumer,&_mutex);
        }
        data = _queue.front();//获取队列头元素
        _queue.pop();//头元素出队列
        pthread_mutex_unlock(&_mutex);
        pthread_cond_signal(&_cond_product);
    }
  };//消费者函数
  void* thr_consumer(void*arg)                                                                                    
  {
    Blockqueue* q=(Blockqueue*)arg;
    int i=0;
    while(1){
      q->QueuePop(i);
      cout<<"_consumer消费者 "<< i<<endl;
    }
    return 0;
  }
  //生产者函数
  void* thr_producer(void*arg)
  {
    Blockqueue* q= (Blockqueue*)arg;
    int i=0 ;
    while(1){
      q->QueuePush(i++);
    }
    return 0;
  }
  int main(){
    pthread_t t[4],pro_tid[4]; //线程变量 当创建线程后值为线程额ID,也是线程的地址
    int ret;
    Blockqueue q;
    //创建四个消费者线程
    for(int i=0;i<4;i++)
    {
      ret=pthread_create(&t[i],NULL,thr_consumer,(void*)(&q));
      if(ret!=0)
      {
        cout<<" thread creataeo"<<endl;
      }
    }
    //四个生产者线程
    for(int i=0;i<4;i++)
        {
   ret=pthread_create(&pro_tid[i],NULL,thr_producer,(void*)(&q));                                                   
            if(ret!=0)
              {
                  cout<<" thread creataeo"<<endl;
                
          }
          
      }
      //获取线程的返回值,NULL代表不关心返回值只为了主函数能退出
    for(int i=0;i<4;i++)
    {
      pthread_join(t[i],NULL);
    }
    for(int i=0;i<4;i++)
    {
      pthread_join(pro_tid[i],NULL);
    }                                                                                                             
    return 0;
  }

makefile编码:
ConsumerQueue:ConsumerQueue.cpp
2 g++ -g $^ -o $@ -lpthread
需要链接库

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值