1. 程式人生 > >程序的互斥控制_消費者生產者經典問題

程序的互斥控制_消費者生產者經典問題

題目:
假定在生產者和消費者之間的公用緩衝池中具有n個緩衝區,消費者不能同時取一個緩衝區的產品,生產者不能同時向同一個緩衝區放入產品。只有緩衝區中有產品時,消費者才可以取產品,只有緩衝區有空時,生產者才可以放入產品。消費者與生產者也不能同時對同一個緩衝區進行操作。
程式碼:

訊號量的設定:
名稱			初值		含義
empty			n		緩衝池中的空閒緩衝區個數
produce			0		緩衝池中產品的個數
mutex			1		同時對緩衝區的操作互斥控制

void producer(){
while(1){
	wait(empty);		//申請空位
	wait(mutex);
	//放入產品操作
signal(mutex); signal(produce); //放置產品 } } void consumer(){ while(1){ wait(produce); //申請產品 wait(mutex); //取出產品操作 signal(mutex); signal(empty); //釋放空位 } } int main(){ consumer.start(); producer.start(); }

分析:
問題相當簡單,需要互斥的操作有兩個:
①.放入產品操作,要滿足:放時不能取,無時不能取
②.取出產品操作,要滿足:拿時不能放,滿時不能放
放時不能取和拿時不能放通過兩個程序對同一個訊號量mutex進行申請即可實現
無時不能取則讓取方(消費者)對produce訊號量進行申請,無則阻塞
滿時不能放則讓放方(生產者)對empty訊號量進行申請,無時阻塞

更進一步的

在此問題上增加要求:消費者要一口氣拿10個產品才退出,在此期間其他消費者不能拿取
那麼,分析一下,只需要將拿取一個產品的操作當做一個整體,對這個整體操作再進行互斥控制,在拿滿十次之前不讓其他程序進入拿取操作即可.
消費者程式碼如下:

新增訊號量:
keep	1		同時可進行取操作的消費者個數
void consumer(){
while(1){
	wait(keep)
	for(int i=0;i<10;i++)
	{
		wait(produce);		//申請產品
		wait(mutex);
		//取出產品操作
		signal(mutex);
		signal(
empty); //釋放空位 } signal(keep) } }

這樣,當其他消費者試圖取操作時,都會對keep訊號量進行詢問,若有人沒取完10個,則會被阻塞在這裡,等待signal(keep)的時候被喚醒.