生产者消费者模型

1.    生产者消费者问题(producer-consumer),有限缓冲多线程同步。生产者线程和消费者线程共享固定大小缓冲区

2.    关键是保证生产者不会再缓冲区满时加入数据,消费者不会在缓冲区空时消耗数据。

3.    解决办法:让生产者在缓冲区满时休眠,等下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒。同样,让消费者在缓冲区空时进入休眠,等到生产者生产数据后再唤醒。

4.    通常采用进程间通信的方法(信号灯法)


#include<iostream>
#include<unistd.h> //需要用到sleep()
#include<pthread.h> //线程库
#include<stdlib.h> //生成随机数rand()需要此头文件
#include<semaphore.h> //需要用到信号量

#define BUFFER_SIZE 10  //缓冲区存储单元设定为10
#define PRODUCER_NUM 6   //设定6个生产者
#define CONSUMER_NUM 6   //设定6个消费者

using namespace std;

typedef int buffer_item;
buffer_item buffer[BUFFER_SIZE]={0};//定义缓冲区每个存储单元都为默认值0

int in = 0 , out = 0;

pthread_mutex_t mutex;//互斥锁
sem_t empty; //信号量的数据类型为结构sem_t,它本质上是一个长整型的数
sem_t full;

//填充数据
void insert_item(buffer_item  item){
buffer[in]=item;
in=(in+1)%BUFFER_SIZE;//取余的目的是使缓存区相当于一个环形的
}
//移除数据
void remove_item(buffer_item* item){
*item=buffer[out];
buffer[out]=0;//取走数据后缓存单元复位
out=(out+1)%BUFFER_SIZE;
}

//生产者
void *producer(void* param){
buffer_item item;
pthread_t tid=pthread_self();
while(1){
sleep(2);
item =1+(10.0*rand()/(RAND_MAX+1.0));//产生1-10的随机数
sem_wait(&empty); //若empty大于0,继续执行,减1;若empty为0,等待其它线程增加了这个值使它不再是0为止
pthread_mutex_lock(&mutex);
insert_item(item);
pthread_mutex_unlock(&mutex);
sem_post(&full);

cout<<"线程id为: "<<tid<<" .....生产者.....在"<<in<<"号缓冲单元中生产了数据:"<<item<<endl;
}
}

//消费者
void *consumer(void* param){
buffer_item item;
pthread_t tid = pthread_self();
while(1){
sleep(2);
sem_wait(&full);
pthread_mutex_lock(&mutex);
remove_item(&item);
pthread_mutex_unlock(&mutex);
sem_post(&empty);

cout<<"线程id为: "<<tid<<" 的消费者在"<<out<<"号缓冲单元上消耗了数据:"<<item<<endl;
}
}

int main(){
pthread_t producerid[PRODUCER_NUM];
pthread_t consumerid[CONSUMER_NUM];
pthread_mutex_init(&mutex , NULL); //初始化互斥锁

pthread_attr_t attr;
pthread_attr_init(&attr);//初始化线程属性

sem_init(&empty , 0 , BUFFER_SIZE);//初始化信号量,初始值为BUFFER_SIZE,中间的参数0代表进程内的线程共享
sem_init(&full , 0 , 0);
        
        int i;
for(i=0 ; i<PRODUCER_NUM ; i++)
pthread_create(&producerid[i] ,&attr ,producer , NULL);

for(i=0 ; i<CONSUMER_NUM ; i++)
pthread_create(&consumerid[i] , &attr ,consumer ,NULL);

for(i = 0 ; i<PRODUCER_NUM ; i++)
pthread_join(producerid[i],NULL);

for(i = 0 ; i<CONSUMER_NUM ;i++)
pthread_join(consumerid[i] ,NULL);

return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值