秦点点丶

秦小晋不弱智智障反而美丽可爱啦!

导航

生产者-消费者问题

    生产者-消费者问题有时也称作有界缓冲区问题。

    两个进程共享一个固定大小的缓冲区,生产者将信息放入缓冲区,消费者从缓冲区中取出信息。

    问题在于 当缓冲区已满,而此时生产者还想向其中放入一个新的数据项情况。其解决办法是让生产者睡眠,待消费者从缓存区取出一个或者多个数据的时候再唤醒它。同样的,当消费者试图从缓存区中取出数据而发现缓存区为空时,消费者就睡眠,直到生产者向其中放入一些数据时再将其唤醒

 1 #define N 100                                      /*缓冲区中的槽数目*/
 2 int count = 0;                                     /*缓冲区中的数据项数目*/
 3 
 4 //producer
 5 void producer(void)    
 6 {
 7   int item;
 8 
 9   while(TRUE){                                     /*无限循环*/
10     item = produce_item();                         /*产生下一新数据项*/
11     if(count == N) sleep();                        /*如果缓冲区满了,就进入休眠状态*/
12     insert_item(item);                             /*将(新)数据项放入缓冲区中*/
13     count = count + 1;                             /*将缓冲区的数据项计数器增1*/
14     if(count == 1) wakeup(consumer);               /*缓冲区空吗?*/
15     }         
16 }
17 
18 //consumer
19 void consumer(void)
20 {
21 while(TRUE){                                       /*无限循环*/
22     if(count == 0) sleep();                        /*如果缓冲区空,则进入休眠状态*/
23     item = remove_item();                          /*从缓冲区中取出一个数据项*/
24     count = count - 1;                             /*将缓冲区的数据项计数器减1*/
25     if(count == N-1) wakeup(producer);             /*缓冲区慢吗?*/
26     consume_item(item);                            /*打印数据项*/
27     }         
28 }

    现在要讨论的是,可能出现竞争条件的状况。其原因是对count的访问未加限制,有可能出现以下情况:缓冲区为空,消费者刚刚读取count的值发现它为0。此时调度程序决定暂停消费者并启动运行生产者。生产者向缓冲区中加一个数据项,count加1,现在count的值变成了1。它推断认为由于count刚才为0,所以消费者此时一定在睡眠,于是生产者调用wakeup来唤醒消费者!

    但是,消费者此时在逻辑上并未睡眠,所以wakeup信号丢失,当消费者下次运行的时候,他将测试先前读到的count值,发现他为0,于是睡眠。生产者迟早会填满整个缓冲区,然后睡眠!

    解决方法:唤醒等待位

posted on 2014-12-16 19:01  秦点点丶  阅读(395)  评论(0编辑  收藏  举报