1、什么是生产者消费者模型?
答:生产者与消费者其实在我们生活中很常见,比如工厂生产商品,我们购买商品,那么这里工厂就是生产者,我们就是消费者。还有一个仓库,当生产者生产出货物,将货物放入仓库,我们消费时货物从仓库发出。这三者共同组成生产者和消费者模型。
2、生产者和消费者模型的特点?
答:一个场所,两个角色,三种关系,这句话就可以描述出生产者与消费者模型,那么我们来解读一下:
一个场所:当然指的就是我们的仓库(也就是缓冲区);
两个角色:就是我们的生产者和消费者;
三种关系:① 生产者与生产者之间是互斥关系;
② 消费者与消费者之间是互斥关系;
③ 生产者与消费者之间是同步 + 互斥关系。
我们实现这三种关系就是为了实现安全操作。也就是说生产者生产的时候,消费者不能消费;消费者消费时,生产者不能生产;缓冲区为空时,消费者不能消费;缓冲区满时,生产者不能生产。这样就保证了安全操作。
3、生产者与消费者模型的好处?
1、解耦:
有了缓冲区之后,生产者与消费者之间的直接依赖关系就减少了,如果二者的行为发生变化(或者代码形式改变),就不会直接影响到对方。
2、支持并发:
如果直接让生产者与消费者之间进行联系,那么二者在代码中就是顺序执行的,就是生产者生产一个,消费者消费掉这个货品。如果双方有一方出现问题,那么程序就会一直阻塞,大大降低效率。所以加上缓冲区后,双方就不必再等待对方完成动作。
3、支持忙闲不均:
如果生产者生产的速度不均衡,导致时快时慢,让消费者来不及消费,那么缓冲区的作用就体现出来了,让消费者来不及处理的数据先放在缓冲区中,等消费者有时间再去处理。减少忙的时间太忙,闲的时间太闲的现象。
我们实现生产者与消费者模型是通过队列当作缓冲区,通过写一个队列类,让生产者将产品放入缓冲区,消费者从缓冲区中取出并消费。
/*实现生产者与消费者模型*/
#include <iostream>
#include <queue>
#include <string>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class BlockQueue{
public:
BlockQueue(int cap = 10)
:_capacity(cap)
{
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_productor, NULL);
pthread_cond_init(&_customer, NULL);
}
~BlockQueue()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_productor);
pthread_cond_destroy(&_customer);
}
void QueuePush(int val)
{
QueueLock();
while(QueueIsFull()){
ProductorWait();
}
_queue.push(val);
QueueUnlock();
CustomerWakeUp();
}
void QueuePop(int *val)
{
QueueLock();
while(QueueIsEmpty()){
CustomerWait();
}
*val = _queue.front();
_queue.pop();
QueueUnlock();
ProductorWakeUp();
}
private:
queue<int> _queue;
int _capacity;
pthread_mutex_t _mutex;
pthread_cond_t _productor;
pthread_cond_t _customer;
private:
void QueueLock(){
pthread_mutex_lock(&_mutex);
}
void QueueUnlock(){
pthread_mutex_unlock(&_mutex);
}
void CustomerWait(){
pthread_cond_wait(&_customer, &_mutex);
}
void CustomerWakeUp(){
pthread_cond_signal(&_customer);
}
void ProductorWait(){
pthread_cond_wait(&_productor, &_mutex);
}
void ProductorWakeUp(){
pthread_cond_signal(&_productor);
}
bool QueueIsEmpty(){
return _queue.empty();
}
bool QueueIsFull(){
return (_queue.size() == _capacity);
}
};
//消费者取产品
void *customer(void *arg)
{
BlockQueue *q = (BlockQueue*)arg;
while(1){
int data;
q->QueuePop(&data);
cout << "get data:" << data << endl;
}
return NULL;
}
//生产者放产品
void *productor(void *arg)
{
BlockQueue *q = (BlockQueue*)arg;
int i = 0;
while(1){
q->QueuePush(i);
cout << "---put data:" << i << endl;
i++;
}
return NULL;
}
int main()
{
BlockQueue q;
pthread_t c_tid[4], p_tid[4];
//创建生产者
for(int i = 0; i < 4; i++){
if(pthread_create(&p_tid[i], NULL, productor, (void*)&q) != 0){
cout << "create thread error" << endl;
return -1;
}
}
//创建消费者
for(int i = 0; i < 4; i++){
if(pthread_create(&c_tid[i], NULL, customer, (void*)&q) != 0){
cout << "create thread error" << endl;
return -1;
}
}
//记得线程等待
for(int i = 0; i < 4; i++){
pthread_join(c_tid[i], NULL);
}
for(int i = 0; i < 4; i++){
pthread_join(p_tid[i], NULL);
}
return 0;
}
结果展示:
由此可以看出生产者生产的速度和消费者消费的速度都很快。