这种方式可以用信号量初值来定义仓库大小,循环生产和消费
生产者:
while(1)
{
pthread_mutex_lock(&mutex);
sem_wait(&sem_full);
生产
sem_post(&sem_empty);
pthread_mutex_unlock(&mutex);
}
消费者:
while(1)
{
pthread_mutex_lock(&mutex);
sem_wait(&sem_empty);
消费
sem_post(&sem_full);
pthread_mutex_unlock(&mutex);
}
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#define PRO_COUNT 3
#define COM_COUNT 3
#define BUFSIZE 5
int buf[BUFSIZE];//仓库
int num=1;//产品编号
int rd_idx=1;//读索引
int wr_idx=1;//写索引
pthread_mutex_t mutex;//互斥
sem_t sem_full;//控制可生产的个数
sem_t sem_empty;//控制可消费的个数
void* pro(void* arg)
{
int id=*(int*)arg;
free(arg);
while(1)
{
sem_wait(&sem_full);
pthread_mutex_lock(&mutex);
printf("%d号生产者开始生产%d\n",id,num);
int i;
for(i=1;i<=BUFSIZE;i++)
{
printf("buf[%d]=%d",i,buf[i]);
if(wr_idx==i)
printf("<=====");
printf("\n");
}
sleep(rand()%2);
buf[wr_idx]=(num++)%(BUFSIZE+1);
num%=BUFSIZE+1;
wr_idx=(wr_idx+1)%(BUFSIZE+1);
printf("%d号生产者生产结束\n",id);
pthread_mutex_unlock(&mutex);
sem_post(&sem_empty);
}
}
void* com(void* arg)
{
int id=*(int*)arg;
free(arg);
while(1)
{
sem_wait(&sem_empty);
pthread_mutex_lock(&mutex);
printf("%d号消费者开始消费%d\n",id,rd_idx);
int i;
for(i=1;i<=BUFSIZE;i++)
{
printf("buf[%d]=%d",i,buf[i]);
if(rd_idx==i)
printf("=====>");
printf("\n");
}
int r=buf[rd_idx];
buf[rd_idx]=-1;
rd_idx=(rd_idx+1)%(BUFSIZE+1);
sleep(rand()%2);
printf("%d号消费者消费结束%d\n",id,r);
pthread_mutex_unlock(&mutex);
sem_post(&sem_full);
}
}
int main()
{
pthread_t tid[PRO_COUNT+COM_COUNT];
//初始化
pthread_mutex_init(&mutex,NULL);
sem_init(&sem_full,0,BUFSIZE);
sem_init(&sem_empty,0,0);
int i=0;
for(i=0;i<=BUFSIZE;i++)
buf[i]=-1;
//创建生产者线程
for(i=0;i<PRO_COUNT;i++)
{
int* p=(int*)malloc(sizeof(int));
*p=i+1;
pthread_create(&tid[i],NULL,pro,(void*)p);
}
//创建消费者线程
for(i=0;i<COM_COUNT;i++)
{
int *p=(int*)malloc(sizeof(int));
*p=i+1;
pthread_create(&tid[i+PRO_COUNT],NULL,com,(void*)p);
}
//等待
for(i=0;i<PRO_COUNT+COM_COUNT;i++)
{
pthread_join(tid[i],NULL);
}
//销毁
sem_destroy(&sem_empty);
sem_destroy(&sem_full);
pthread_mutex_destroy(&mutex);
}
执行结果:
3号生产者开始生产1
buf[1]=-1<=====
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=-1
3号生产者生产结束
2号生产者开始生产2
buf[1]=1
buf[2]=-1<=====
buf[3]=-1
buf[4]=-1
buf[5]=-1
2号生产者生产结束
2号生产者开始生产3
buf[1]=1
buf[2]=2
buf[3]=-1<=====
buf[4]=-1
buf[5]=-1
2号生产者生产结束
1号消费者开始消费1
buf[1]=1=====>
buf[2]=2
buf[3]=3
buf[4]=-1
buf[5]=-1
1号消费者消费结束1
3号消费者开始消费2
buf[1]=-1
buf[2]=2=====>
buf[3]=3
buf[4]=-1
buf[5]=-1
3号消费者消费结束2
3号生产者开始生产4
buf[1]=-1
buf[2]=-1
buf[3]=3
buf[4]=-1<=====
buf[5]=-1
3号生产者生产结束
3号生产者开始生产5
buf[1]=-1
buf[2]=-1
buf[3]=3
buf[4]=4
buf[5]=-1<=====
3号生产者生产结束
1号消费者开始消费3
buf[1]=-1
buf[2]=-1
buf[3]=3=====>
buf[4]=4
buf[5]=5
1号消费者消费结束3
1号消费者开始消费4
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=4=====>
buf[5]=5
1号消费者消费结束4
2号消费者开始消费5
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=5=====>
2号消费者消费结束5
2号生产者开始生产0
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=-1
2号生产者生产结束
符合预期结果。。。