运行在VS2022,x86,Debug下。
32. 生产者消费者模式
- 解耦生产者和消费者之间的关系,即生产者和消费者只依赖缓冲区,而不相互依赖。
- 应用:多线程并发编程,可以解决生产者和消费者之间的同步问题。
- 实现
- 生产者:负责产生数据的模块。
- 消费者:负责处理数据的模块。
- 中介:缓冲区。
- 代码如下。
lambda表达式在condition_variable::wait()中充当断言。
cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>
using namespace std;
const int BUFFER_SIZE = 10; //缓冲区大小
queue<int> buffer; //缓冲区, 用于存放数据
mutex mtx; //互斥量,用于保护共享资源
condition_variable prod_cv; // 生产者条件变量,用于线程间的同步
condition_variable cons_cv; // 消费者条件变量
//生产者
void producer()
{
for (int i = 0; i < 20; i++) //循环生产20个数据
{
unique_lock<mutex> lock(mtx); //独占锁,确保同一时刻只有一个线程访问临界区
prod_cv.wait(lock, [] { return buffer.size() < BUFFER_SIZE; }); //等待条件满足,即缓冲区不满
buffer.push(i);
cout << "Producer ID:" << this_thread::get_id() << " Produced: " << i << std::endl;
lock.unlock(); //解锁互斥量
cons_cv.notify_all(); //通知消费者
this_thread::sleep_for(std::chrono::milliseconds(500)); //睡眠, 模拟生产过程
}
}
//消费者
void consumer()
{
for (int i = 0; i < 20; i++) //循环消费20个数据
{
unique_lock<std::mutex> lock(mtx);
cons_cv.wait(lock, [] { return !buffer.empty(); }); //等待条件满足,即缓冲区不为空
cout << "Consumer ID:" << this_thread::get_id() << " Consumed: " << buffer.front() << endl;
buffer.pop();
lock.unlock();
prod_cv.notify_all(); //通知生产者
this_thread::sleep_for(std::chrono::milliseconds(800));
}
}
int main()
{
const int num_producers = 2; //生产者数量
const int num_consumers = 2; //消费者数量
vector<thread> producer_threads;
vector<thread> consumer_threads;
for (int i = 0; i < num_producers; i++) //创建生产者线程
producer_threads.emplace_back(producer);
for (int i = 0; i < num_consumers; i++) //创建消费者线程
consumer_threads.emplace_back(consumer);
for (auto&& thread : producer_threads) //等待所有生产者线程结束
thread.join();
for (auto&& thread : consumer_threads) //等待所有消费者线程结束
thread.join();
return 0;
}