目录
一.生产者消费者概念
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取。
阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
这个阻塞队列就是用来给生产者和消费者解耦的。
![](https://i-blog.csdnimg.cn/blog_migrate/eb2bf76c0341cc725f2f898965e77583.png)
生产者消费者模型是多线程同步与互斥的一个经典场景,其特点:
- 三种关系: 生产者和生产者(互斥关系)、消费者和消费者(互斥关系)、生产者和消费者(互斥关系、同步关系)。
- 两种角色: 生产者和消费者。(通常由进程或线程承担)
- 一个交易场所: 通常指的是内存中的一段缓冲区。(可以自己通过某种方式组织起来)
二.模拟实现基于阻塞队列的生产消费模型
2.1概念
1.阻塞队列是会被生产者和消费者同时访问的临界资源,因此我们需要用一把互斥锁将其保护来。
2.生产者线程要向阻塞队列当中Push数据,若阻塞队列已经满了,那么此时该生产者需要进行等待,直到阻塞队列中有空间时再被唤醒。消费者线程要从阻塞队列当中Pop数据,若阻塞队列为空,那么此时该消费者需要进行等待,直到阻塞队列中有新的数据时再被唤醒。
3.需要用到两个条件变量,一个条件变量用来描述队列为空,另一个条件变量用来描述队列已满。若是队列满了,生产者要进行等待,若是队列为空,消费者要进行等待。
4.当生产者或者消费者执行后,都要去唤醒另一方。
2.2构造阻塞队列
BlockQueue.hpp代码:
#include <iostream>
#include <queue>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
using namespace std;
const int capacity=5;
template<class T>
class BlockQueue
{
public:
BlockQueue(int size=capacity)//初始化
:size_(size)
{
pthread_mutex_init(&mutex_,nullptr);
pthread_cond_init(&proCond_,nullptr);
pthread_cond_init(&conCond_,nullptr);
}
~BlockQueue()//变量的销毁
{
pthread_mutex_destroy(&mutex_);
pthread_cond_destroy(&proCo