操作系统生产者和消费者问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
生产者-消费者问题是一个经典的进程同步问题,已经属于化石级别的了。该问题最早由Dijkstra 提出,用以演示他提出的信号量机制。要求设计在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。
要求设计并实现一个进程,该进程拥有一个生产者线程和一个消费者线程,它们使用N个不同的缓冲区(N为一个自定义的确定的数值,例如N=32)。需要使用如下信号量:
•一个互斥信号量,用以阻止生产者线程和消费者线程同时操作缓冲区列表;
•一个信号量,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;
•一个信号量,消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号;
看代码吧:
//pv操作:生产者与消费者经典问题
//author:leaf
#include
#include
#include
#include
#include
#define M 32 /*缓冲数目*/
#define P(x)sem_wait(&x)
#define V(x)sem_post(&x)
int in = 0;/*生产者放置产品的位置*/
int out = 0;/*消费者取产品的位置*/
int buff[M]={0};/*缓冲初始化为0,开始时没有产品*/
sem_t empty_sem;/*同步信号量,当满了时阻止生产者
放产品*/
sem_t full_sem;/*同步信号量,当没产品时阻止消费者消费*/
pthread_mutex_t mutex;/*互斥信号量,一次只有一个线程访问缓冲*/
/*
*output the buffer
*/
void print()
{
int i;
for(i = 0; i < M; i++)
printf("%d ", buff[i]);
printf("\n");
}
/*
*producer
*/
void*producer()
{
for(;;)
{
sleep(1);
P(empty_sem);
pthread_mutex_lock(&mutex);
in = in % M;
printf("(+)produce a product. buffer:");
buff[in]= 1;
print();
++in;
pthread_mutex_unlock(&mutex);
V(full_sem);
}
}
/*
*consumer
*/
void*consumer()
{
for(;;)
{
sleep(2);
P(full_sem);
pthread_mutex_lock(&mutex);
out = out % M;
printf("(-)consume a product. buffer:");
buff[out]= 0;
print();
++out;
pthread_mutex_unlock(&mutex);
V(empty_sem);
}
}
void sem_mutex_init()
{
/*
*semaphore initialize
*/
int init1 = sem_init(&empty_sem, 0, M);
int init2 = sem_init(&full_sem, 0, 0);
if((init1 != 0)&&(init2 != 0))
{
printf("sem init failed \n");
exit(1);
}
/*
*mutex initialize
*/
int init3 =pthread_mutex_init(&mutex,NULL);
if(init3 != 0)
{
printf("mutex init failed \n");
exit(1);
}
}
int main()
{
pthread_t id1;
pthread_t id2;
int i;
int ret;
sem_mutex_init();
/*create the producer thread*/
ret =pthread_create(&id1,NULL, producer,NULL);
if(ret != 0)
{
printf("producer creation failed \n");
exit(1);
}
/*create the consumer thread*/
ret =pthread_create(&id2,NULL, consumer,NULL);
if(ret != 0)
{
printf("consumer creation failed \n");
exit(1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
exit(0);
}