背景
在 C++ 中使用一个可调用对象构造一个 std::thread 对象,即可创建一个线程;使用互斥量 std::mutex 来确保多个线程对共享数据的读写操作的同步问题;使用 std::condition_variable 来解决线程执行顺序的同步问题。
生产者和消费者模式
在 C++ 中可以使用 std::condition_variable 来实现生产者和消费者模式:生产者在缓冲区未满时不断添加数据,并唤醒消费者进行数据读取;消费者在缓存区为空时阻塞等待生产者的唤醒,并在读取数据后唤醒等待的生产者可以继续添加数据。
代码示例
#include "thread"
#include "iostream"
#include "queue"
#include "condition_variable"
#include <mutex>
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;
}
执行结果如下: