首页 > 代码库 > 生产者-消费者问题
生产者-消费者问题
生产者-消费者问题有时也称作有界缓冲区问题。
两个进程共享一个固定大小的缓冲区,生产者将信息放入缓冲区,消费者从缓冲区中取出信息。
问题在于 当缓冲区已满,而此时生产者还想向其中放入一个新的数据项情况。其解决办法是让生产者睡眠,待消费者从缓存区取出一个或者多个数据的时候再唤醒它。同样的,当消费者试图从缓存区中取出数据而发现缓存区为空时,消费者就睡眠,直到生产者向其中放入一些数据时再将其唤醒
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 //consumer19 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,于是睡眠。生产者迟早会填满整个缓冲区,然后睡眠!
解决方法:唤醒等待位
生产者-消费者问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。