生产者消费者模式
概念
生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几点:
1)生产者生产的时候消费者不能消费
2)消费者消费的时候生产者不能生产
3)缓冲区空的时候消费者不能消费
4)缓冲区满的时候生产者不能生产
代码实现
下面我使用线程同步的原语条件变量和互斥锁来实现生产者消费者模式,用链表当作缓冲区资源,生产者生产的时候往缓冲区中插入随机数,消费者消费的时候从缓冲区中取出随机数并打印
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
typedef int Elemtype;
int size = 0;
typedef struct ListNode
{
Elemtype data;
struct ListNode *next;
}ListNode;
void pushFront(ListNode **phead,int val)
{
ListNode *p = (ListNode*)malloc(sizeof(ListNode));
p->data = val;
if(*phead == NULL)
{
*phead = p;
}
p->next = *phead;
*phead = p;
size += 1;
}
int popFront(ListNode **phead)
{
int val;
val = (*phead)->data;
ListNode*p = *phead;
*phead = (*phead)->next;
free(p);
p = NULL;
size -= 1;
return val;
}
ListNode* list = NULL;
pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
void* produce(void *arg)
{
for(;;)
{
pthread_mutex_lock(&mylock);
sleep(1);
while(size != 0)
{
pthread_cond_wait(&mycond, &mylock);
}
for(int i = 0; i < 5;i++)
{
int data = rand() % 100;
pushFront(&list, data);
printf("生产者生产了:%d ,当前仓库大小为: %d\n", data,size);
}
pthread_mutex_unlock(&mylock);
pthread_cond_signal(&mycond);//唤醒消费者线程可以消费了
}
}
void* customer(void *arg)
{
for(;;)
{
pthread_mutex_lock(&mylock);
sleep(1);
while(size == 0)
{
pthread_cond_wait(&mycond, &mylock);
}
int data = popFront(&list);
printf("获取货物:%d,当前仓库大小:%d\n",data,size);
pthread_mutex_unlock(&mylock);
pthread_cond_signal(&mycond);//唤醒生产者线程,看仓库为不为空
}
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, produce, NULL);
pthread_create(&tid2, NULL, customer, NULL);
pthread_join(&tid1, NULL);
pthread_join(&tid2, NULL);
pthread_cond_destroy(&mycond);
pthread_mutex_destroy(&mylock);
return 0;
}
运行结果:
生产者/消费者模式的优点
1、解耦。因为多了一个缓冲区,所以生产者消费者并不直接相互调用,这样生产者和消费者的代码发生变化,都不会对对方产生影响,这样其实就是把生产者和消费者之间的强耦合解开了,变为了生产者和缓冲区/消费者和缓冲区之间的弱耦合
2、通过平衡生产者和消费者的处理能力来提高整体处理数据的速度,如果消费者直接从消费者那里拿数据,如果生产者生产的速度很慢,但消费者消费的速度很快,那消费者就得占用CPU的时间片白白等在那边,有了生产者消费者模型,生产者消费者就是两个独立的并发体,生产者把生产出来的数据往缓冲区一丢就好了,不必管消费者;消费者也是,从缓冲区去拿数据就好了,也不必管生产者,缓冲区满了就 不生产了,缓冲区空了就不消费,使 生产者消费者的处理能力达到一个动态平衡。