操作系统实验:生产者消费者问题
问题:
在系统中有 个缓冲区(每个可以放1个产品)构成的仓库。有 个生产者 ,每个生产者 可以生产 个产品。有 个消费者 ,每个消费者消费若干个产品,直到消费完所有的产品为止,即 ,其中 是消费者 实际消费的产品个数。
输入:生产者个数 、消费者个数 、缓冲区个数 、每个生产者生产产品的个数 等。
输出:生产者-消费者并发执行的过程、每个进程的状态变化。如:
(1)生产者 将第X个产品放入仓库;
(2)消费者 从仓库中消费第Y个产品;
(3)生产者 阻塞;
(4)消费者 阻塞;
(5)生产者 被唤醒;
(6)消费者 被唤醒。
pc.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#include<pthread.h>
int PRODUCER; //生产者数量
int CONSUMER; //消费者数量
int BUFFER;//缓冲区数量
int k[100];
int flagp[100];
int flagc[100];
int kp[100];
int kc[100];
sem_t empty,full;//同步信号量
pthread_mutex_t mutex;//互斥信号量
int buffer[100]; //缓冲区
int sum=0;
int producer_id=0,consumer_id=0;//生产者消费者ID
int index_in=0,index_out=0;//生产者 消费者 存放 消费的位置
void print()//输出缓冲区
{
int i;
printf("\n缓冲区:\n");
for(i=0;i<BUFFER;i++)
{
printf("---");
}
printf("\n");
for(i=0;i<BUFFER;i++)
printf("|%d|",buffer[i]);
printf("\n");
for(i=0;i<BUFFER;i++)
{
printf("---");
}
printf("\n\n");
}
void *Producer()//生产者函数
{
int ID=++producer_id;
while(kp[ID]<k[ID])
{
if(empty.__align==0){
printf("生产者%d阻塞 \n",ID);
flagp[ID]=1;
}
sleep(3);
sem_wait(&empty);
pthread_mutex_lock(&mutex);
index_in=index_in%BUFFER;
if(flagp[ID]==1){
printf("生产者%d唤醒 \n",ID);
flagp[ID]=0;
}
buffer[index_in]=1;//缓冲区置1
kp[ID]++;
printf("生产者 %d 将第%d个产品放入仓库 \n",ID,kp[ID]);
print();//输出缓冲区情况
index_in++;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
if(kp[ID]<k[ID])
exit(0);
}
void *Consumer()//消费者函数
{
int ID=++consumer_id;
flagc[ID]=0;
while(sum)
{
if(full.__align==0){
printf("消费者%d阻塞 \n",ID);
flagc[ID]=1;
}
sleep(3);
sem_wait(&full);
pthread_mutex_lock(&mutex);
index_out=index_out%BUFFER;
if(flagc[ID]==1){
printf("消费者%d唤醒 \n",ID);
flagc[ID]=0;
}
buffer[index_out]=0;//缓冲区置0
kc[ID]++;
sum--;
printf("\033[01;34m消费者 %d 在仓库中消费了第%d个产品\033[0m\n",ID,kc[ID]);
print();//输出缓冲区情况
index_out++;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
if(sum==0)
exit(0);
}
int main()
{
int i;
printf("输入生产者个数:");
scanf("%d",&PRODUCER);
printf("输入消费者个数:");
scanf("%d",&CONSUMER);
printf("输入缓冲区个数:");
scanf("%d",&BUFFER);
printf("输入每个生产者生产产品的个数:");
for(i=1;i<PRODUCER+1;i++){
scanf("%d",&k[i]);
sum+=k[i];
}
printf("\n");
int rthread[18];
pthread_t producer[PRODUCER];//生产者
pthread_t consumer[CONSUMER];//消费者
int sinit1=sem_init(&empty,0,BUFFER);//初始化同步信号量
int sinit2=sem_init(&full,0,0);
int minit =pthread_mutex_init(&mutex,NULL);//初始化互斥信号量
if(sinit1 && sinit2)
{
printf("信号量初始化失败 /n");
exit(1);
}
if(minit)
{
printf("信号量初始化失败 /n");
exit(1);
}
for(i=0;i<PRODUCER;i++)//创建生产者线程
{
rthread[i]=pthread_create(&producer[i], NULL, Producer, NULL);
if(rthread[i])
{
printf("生产者 %d 创建失败 /n", i);
exit(1);
}
}
for(i=0;i<CONSUMER;i++)//创建消费者线程
{
rthread[i]=pthread_create(&consumer[i], NULL, Consumer,NULL);
if(rthread[i])
{
printf("消费者 %d 创建失败 /n", i);
exit(1);
}
}
for(i=0;i<PRODUCER;i++)//销毁生产者线程
{
pthread_join(producer[i],NULL);
}
for(i=0;i<CONSUMER;i++)//销毁生产者线程
{
pthread_join(consumer[i],NULL);
}
exit(0);
}