生产者消费者问题

生产者消费者问题

ID:11938462

大小:35.50 KB

页数:9页

时间:2018-07-15

生产者消费者问题_第1页
生产者消费者问题_第2页
生产者消费者问题_第3页
生产者消费者问题_第4页
生产者消费者问题_第5页
资源描述:

《生产者消费者问题》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、生产者消费者问题生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者

2、放入一个或者多个数据时再唤醒它。听起来好像蛮对的,无懈可击似的,但其实在实现时会有一个竞争条件存在的。为了跟踪缓冲区中的消息数目,需要一个变量count。如果缓冲区最多存放N个消息,则生产者的代码会首先检查count是否达到N,如果是,则生产者休眠;否则,生产者向缓冲区中放入一个消息,并增加count的值。消费者的代码也与此类似,首先检测count是否为0,如果是,则休眠;否则,从缓冲区中取出消息并递减count的值。同时,每个进程也需要检查是否需要唤醒另一个进程。代码可能如下://缓冲区大小#d

3、efineN100intcount=0;//跟踪缓冲区的记录数/*生产者进程*/voidprocedure(void){intitem;//缓冲区中的数据项while(true)//无限循环{item=produce_item();//产生下一个数据项if(count==N)//如果缓冲区满了,进行休眠{sleep();}insert_item(item);//将新数据项放入缓冲区count=count+1;//计数器加1if(count==1)//表明插入之前为空,{//消费者等待wakeup(

4、consumer);//唤醒消费者}}}/*消费者进程*/voidconsumer(void){intitem;//缓冲区中的数据项while(true)//无限循环{if(count==0)//如果缓冲区为空,进入休眠{sleep();}item=remove_item();//从缓冲区中取出一个数据项count=count-1;//计数器减1if(count==N-1)//缓冲区有空槽{//唤醒生产者wakeup(producer);}consume_item(item);//打印出数据项}}

5、看上去很美,哪里出了问题,这里对count的访问是有可能出现竞争条件的:缓冲区为空,消费者刚刚读取count的值为0,而此时调度程序决定暂停消费者并启动执行生产者。生产者向缓冲区中加入一个数据项,count加1。现在count的值变成了1.它推断刚才count为0,所以此时消费者一定在休眠,于是生产者开始调用wakeup(consumer)来唤醒消费者。但是,此时消费者在逻辑上并没有休眠,所以wakeup信号就丢失了。当消费者下次运行时,它将测试先前读到的count值,发现为0(注意,其实这个时刻

6、count已经为1了),于是开始休眠(逻辑上)。而生产者下次运行的时候,count会继续递增,并且不会唤醒consumer了,所以迟早会填满缓冲区的,然后生产者也休眠,这样两个进程就都永远的休眠下去了。1,使用信号量解决生产者-消费者问题首先了解一下信号量吧,信号量是E.W.Dijkstra在1965年提出的一种方法,它是使用一个整型变量来累计唤醒的次数,供以后使用。在他的建议中,引入了一个新的变量类型,称为信号量(semaphore),一个信号量的取值可以为0(表示没有保存下来的唤醒操作)或者为

7、正值(表示有一个或多个唤醒操作)。并且设立了两种操作:down和up(分别为一般化后的sleep和wakeup,其实也是一般教科书上说的P/V向量)。对一个信号量执行down操作,表示检查其值是否大于0,如果该值大于0,则将其值减1(即用掉一个保存的唤醒信号)并继续;如果为0,则进程休眠,而且此时down操作并未结束。另外,就是检查数值,修改变量值以及可能发生的休眠操作都作为单一的,不可分割的原子操作来完成。下面开始考虑用信号量来解决生产者-消费者问题了,不过在此之前,再次分析一下这个问题的本质会

8、更清晰点:问题的实质在于发给一个(尚)未休眠进程(如上的消费者进程在只判断了count==0后即被调度出来,还未休眠)的wakeup信号丢失(如上的生产者进程在判断了count==1后以为消费者进程休眠,而唤醒它)了。如果它没有丢失,则一切都会很好。#defineN100//缓冲区中的槽数目typedefintsemaphore;//信号量一般被定义为特殊的整型数据semaphoremutex=1;//控制对临界区的访问semaphoreempty=N;//计数缓冲区中的空槽数目s

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。