生产者和消费者

这篇博客介绍了如何使用pthread库和C++11的条件变量进行多线程间的同步与通信。通过示例展示了生产者消费者问题的解决方案,解释了队列满和空时线程的等待与唤醒机制。同时对比了两种实现方式的差异和兼容性。
摘要由CSDN通过智能技术生成

1.linux版本:

#include<iostream>
#include<queue>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
  
#define NUM 8  
  
class BlockQueue
{
private:
  std::queue<int> q;
  int cap;
  pthread_mutex_t mutex;
  pthread_cond_t full;
  pthread_cond_t empty;

private:
  void LockQueue()  //队列加锁
  {
    pthread_mutex_lock(&mutex);
  }
  void UnlockQueue()  //队列解锁
  {
    pthread_mutex_unlock(&mutex);
  }
  void ProductWait()  //队列满,生产者等待
  {
    pthread_cond_wait(&full,&mutex);
  }
  void ConsumeWait()  //队列空,消费者等待
  {
    pthread_cond_wait(&empty,&mutex);
  }
  void NotifyProduct()  //队列不为满时,通知生产者
  {
    pthread_cond_signal(&full);
  }
  void NotifyConsume()  //队列不为空时,通知消费者
  {
    pthread_cond_signal(&empty);
  }
  bool IsEmpty()
  {
    return (q.size() == 0 ? true : false);
  }
  bool IsFull()
  {                                                                                                                                          
  return (q.size() == cap ? true : false);
  }
public:
  BlockQueue(int _cap = NUM):cap(_cap) //构造函数
  {
    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&full,NULL);
    pthread_cond_init(&empty,NULL);
  } 
  void PushData(const int &data)
  {
    LockQueue();
    while(IsFull()) //队列满
    {
      NotifyConsume();
      std::cout<<"queue full,notify consume data,product stop!!"<<std::endl;
      ProductWait();
    }
    //队列不满,生产者插入数据,通知消费者队列中已经有数据了
    q.push(data);
    NotifyConsume();
    UnlockQueue();
  }
  void PopData(int &data)
  {                                                                                                                                          
    LockQueue();
    while(IsEmpty())  //队列为空
    { 
      NotifyProduct();
      std::cout<<"queue empty,notify product data,consume stop!!"<<std::endl;
      ConsumeWait();
    }
    //队列不为空
    data = q.front();
    q.pop();
    NotifyProduct();
    UnlockQueue();
  }
  ~BlockQueue()
  {
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&full);
    pthread_cond_destroy(&empty);
  }
};
  
//消费者
void* consumer(void* arg)
{
  BlockQueue *bqp = (BlockQueue*)arg;
  int data;
  for(;;)                                                                                                                                      
  {
    bqp->PopData(data);
    std::cout<<"Consume data done: "<<data<<std::endl;
  }
}
                              
//生产者
void* producter(void* arg)
{
  BlockQueue *bqp = (BlockQueue*)arg;
  srand((unsigned long)time(NULL));
  for(;;)
  {
    int data = rand()%1024;
    bqp->PushData(data);
    std::cout<<"Product data done: "<<data<<std::endl;
    // sleep(1);
  }
}
  
int main()
{
  BlockQueue bq;
  pthread_t c,p;
    
  pthread_create(&c,NULL,consumer,(void*)&bq);
  pthread_create(&p,NULL,producter,(void*)&bq);

  pthread_join(c,NULL);
  pthread_join(p,NULL);
    
  return 0;
}

备注:

条件变量的用法,参考下面这个连接:

https://blog.csdn.net/icechenbing/article/details/7662026

 

2. c++ 11 中,兼容各个平台:

#include <deque>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <iostream>


std::deque<int> q;
std::mutex mu;
std::condition_variable cond;

void function_1() //生产者
{
    int count = 10;
    while (count > 0) 
    {
        std::unique_lock<std::mutex> locker(mu);
        q.push_front(count);
		std::cout << "t1 push a value: " << count << std::endl;
        locker.unlock();
        cond.notify_one();  // Notify one waiting thread, if there is one.
        std::this_thread::sleep_for(std::chrono::seconds(1));
        count--;
    }
}

void function_2() //消费者
{
    int data = 0;
    while (data != 1) 
    {
        std::unique_lock<std::mutex> locker(mu);
        while (q.empty())
            cond.wait(locker); // Unlock mu and wait to be notified
        data = q.back();
        q.pop_back();
        locker.unlock();
        std::cout << "t2 got a value from t1: " << data << std::endl;
    }
}
int main() 
{
    std::thread t1(function_1);
    std::thread t2(function_2);
    t1.join();
    t2.join();
    return 0;
}

备注:

条件变量的用法,参考下面这个连接:

https://www.cnblogs.com/chenyunf22/p/12775357.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值