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;}
执行结果如下: