什么是生产者消费者模型
生产者消费者模式通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通信,而是通过阻塞队列进行通信。生产者生产完数据后不等待消费者处理,直接放入阻塞队列;消费者不从生产者处获取数据,而是从阻塞队列中取。阻塞队列相当于一个缓冲区,平衡了消费者和生产者的处理能力,实现了二者的解耦。

超市的现实例子
生活中买东西通常去超市而不是直接找供货商。假如需要买一桶方便面,直接找供货商可能不会成功,因为工厂生产是批量进行的,单件购买会导致成本过高且库存积压。现实生活中,供货商通过超市进行生产和消费的解耦。消费者(人)不需要直接向生产者(供货商)要数据,只需从超市(缓冲区)拿取即可。这样既平衡了处理能力,又避免了直接耦合带来的效率问题。
线程视角下的生产者消费者模型
生产者消费者模式本质上是线程间如何安全高效地进行通信。生产者负责生产数据的线程,消费者负责处理数据的线程,而超市则是一段具有特定结构的内存空间。由于生产者和消费者的数据通过这段共享内存空间通信,因此会产生各种并发问题:
- 消费者 VS 消费者:互斥。当资源充足时竞争不明显,但当资源稀缺(如只剩一桶方便面)时,消费者之间存在激烈的竞争关系,属于互斥。
- 生产者 VS 生产者:互斥。多个生产者同时向队列写入数据,存在竞争关系,需要互斥保护。
- 生产者 VS 消费者:互斥与同步。互斥体现在记录人员记录货物时消费者不可拿走;同步体现在队列为空时消费者需等待生产者供货,队列已满时生产者需等待消费者消费。
main 函数
int main() {
// 设置随机种子
srand(time(nullptr));
// 创建阻塞队列
BlockQueue<Task> *bq = new BlockQueue<Task>;
pthread_t c[3], p[5];
// 创建多生产者线程
for (int i = 0; i < 5; i++) {
pthread_create(p + i, nullptr, Producer, bq);
}
// 创建多消费者线程
for (int i = 0; i < 3; i++) {
pthread_create(c + i, nullptr, Consumer, bq);
}
( i = ; i < ; i++) {
(p[i], );
}
( i = ; i < ; i++) {
(c[i], );
}
;
}




