> 文档中心 > C++ 使用条件变量实现生产者和消费者模式

C++ 使用条件变量实现生产者和消费者模式


背景

在 C++ 中使用一个可调用对象构造一个 std::thread 对象,即可创建一个线程;使用互斥量 std::mutex 来确保多个线程对共享数据的读写操作的同步问题;使用 std::condition_variable 来解决线程执行顺序的同步问题。

生产者和消费者模式

在 C++ 中可以使用 std::condition_variable 来实现生产者和消费者模式:生产者在缓冲区未满时不断添加数据,并唤醒消费者进行数据读取;消费者在缓存区为空时阻塞等待生产者的唤醒,并在读取数据后唤醒等待的生产者可以继续添加数据。
在这里插入图片描述

代码示例

#include "thread"#include "iostream"#include "queue"#include "condition_variable"#include using namespace std;class ProducerAndConsumerDemo{public:  void producerNumber();//生产数据  void consumerNumber();//消费数据private:  const int dataSize = 1000;//总数据量  queue<int> listBuffer;//数据缓存区  const int bufferSize = 10;//缓存区大小  condition_variable bufferNotEmpty;//信号量--缓存区有数据了  condition_variable bufferNotFull;//信号量--缓存区不满了  mutex m_mutex;//互斥量};void ProducerAndConsumerDemo::producerNumber(){  for (int i = 0; i < dataSize; ++i)  {    {      unique_lock<mutex> locker(m_mutex);      bufferNotFull.wait(locker, [&]() { return listBuffer.size() < bufferSize; });//缓存区满了则阻塞      listBuffer.push(i);      cout << "生产者---生产了数字:" << i << ",当前 bufferSize:" << listBuffer.size() << endl;    }//解锁互斥量    bufferNotEmpty.notify_one();    this_thread::sleep_for(chrono::milliseconds(1000));//模拟生产耗时  }}void ProducerAndConsumerDemo::consumerNumber(){  while (true)  {    {      unique_lock<mutex> locker(m_mutex);      bufferNotEmpty.wait(locker, [&]() {return listBuffer.size() > 0; });//缓冲区为空则阻塞      int i = listBuffer.front(); listBuffer.pop();      cout << "消费者---消费了数字:" << i << ",当前 bufferSize:" << listBuffer.size() << endl;    }//解锁互斥量    bufferNotFull.notify_one();    this_thread::sleep_for(chrono::milliseconds(2000));//模拟消费耗时  }}int main(){  ProducerAndConsumerDemo pcDemo;  thread consumerThread(&ProducerAndConsumerDemo::producerNumber,&pcDemo);  thread producerThread(&ProducerAndConsumerDemo::consumerNumber, &pcDemo);    producerThread.join();  consumerThread.join();system("pause");    return 0;}

执行结果如下:
在这里插入图片描述