简单的生产者消费者模型
假设存在 A、B 两个线程,二者共享一块内存缓冲区,A 线程负责生产内容写入缓冲区,B 线程负责从缓冲区取出并消耗内容,其中 A 线程就是生产者,B 线程就是消费者
生产者消费者模型出现的原因
当生产线程的生产速度与消费线程的消费速度不匹配时
- 生产速度 > 消费速度
- 生产线程必须等待消费线程,防止出现内存存储空间不足
- 生产速度 < 消费速度
通过让线程共享一块内存缓冲区,达到两个线程之间解耦的效果。生产线程只需要考虑缓冲区非满状态时处于激活状态生产产品,消费线程只需要考虑缓冲区非空状态时处于激活状态消费产品。
模型特点
- 缓冲区满时,生产者不写入,进入休眠状态,直到缓冲区不为满(接收消费者唤醒信号)
- 缓冲区空时,消费者不读取,进入休眠状态,直到缓冲区不为空(接收生产者唤醒信号)
简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| std::condition_variable cv;
bool production_done = false; bool product_ready = false;
std::mutex mtx;
std::queue<int> Productions;
void Producer() { for(int i=0; i<10; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::unique_lock<std::mutex> lock(mtx); Productions.push(i); std::cout << "Producing: " << i << std::endl; product_ready = true; cv.notify_all(); } production_done = true; }
void Consumer() { std::unique_lock<std::mutex> lock(mtx); while(!production_done || !Productions.empty()) { while(!product_ready) { cv.wait(lock); } while(!Productions.empty()) { std::cout << "Consuming: " << Productions.front() << std::endl; Productions.pop(); }
product_ready = false; } }
void Test_MySPSC() { std::thread t1(Producer); std::thread t2(Consumer); t1.join(); t2.join(); }
|