生产者消费者模型

生产者与消费者模型
    生产者:生产数据的线程
    消费者:使用数据的线程
    仓库:临时存储数据的缓冲区(仓库解决生产、消费不匹配的问题)

    可能产生的问题:
        生产快于消费:仓库爆满,撑死
        消费快于生产:仓库空虚,饿死
    利用条件变量来解决以上问题:
        当缓冲区满的时候,生产者睡入条件变量(full),并通知消费者全部醒了(empty)
        当缓冲区空的时候,消费者睡入条件变量(empty),并通知生产者全部醒来(full)
    
    应用:利用生产者消费者模型构建 线程池\数据池
    了解:哲学家就餐问题

以下代码是基于生产者消费者,在仓库里使用的案例

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

#define BUF_MAX 20

//	仓库
char buf[BUF_MAX];

//	仓库中数据的数量
int cnt = 0;

//	仓库满的条件变量
pthread_cond_t full = PTHREAD_COND_INITIALIZER;
//	仓库空的条件变量
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
//	访问仓库的互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//	显示仓库情况
void show_buf(const char* who,const char* dir,char data)
{
	for(int i=0; i<cnt; i++)
	{
		printf("%c ",buf[i]);	
	}
	printf("%s %c %s\n",dir,data,who);
}

//	生产者线程函数
void* producer(void* arg)
{
	for(;;)
	{
		//	加锁
		pthread_mutex_lock(&mutex);

		while(BUF_MAX <= cnt)
		{
			printf("满仓\n");
			//	睡入满仓条件变量并解锁
			pthread_cond_wait(&full,&mutex);
		}

		//	生产数据
		char data = 'A' + rand()%26;
		buf[cnt++] = data;
		show_buf("生产者","<-",data);

		//	解锁
		pthread_mutex_unlock(&mutex);
		//	仓库有数据 唤醒消费者
		pthread_cond_signal(&empty);
		usleep(rand()%10*100000);
	}
}

//	消费者线程函数
void* consumer(void* arg)
{
	for(;;)
	{
		//	加锁
		pthread_mutex_lock(&mutex);

		while(0 >= cnt)
		{
			printf("空仓\n");
			//	睡入满仓条件变量并解锁
			pthread_cond_wait(&empty,&mutex);
		}

		//	消费数据
		char data = buf[--cnt];
		show_buf("消费者","->",data);

		//	解锁
		pthread_mutex_unlock(&mutex);
		//	仓库有空位置 唤醒生产者
		pthread_cond_signal(&full);
		
		usleep(rand()%10*100000);
	}
}
int main(int argc,const char* argv[])
{
	pthread_t tid[10];
	for(int i=0; i<5; i++)
	{
		pthread_create(&tid[i],NULL,producer,NULL);
	}
	for(int i=5; i<10; i++)
	{
		pthread_create(&tid[i],NULL,consumer,NULL);
	}

	for(int i=0; i<10; i++)
	{
		pthread_join(tid[i],NULL);	

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值