一組生產者程序和一組消費者程序共享乙個初始為空、大小為n的緩衝區,只有緩衝區沒滿時,生產者才能把訊息放入到緩衝區,否則必須等待;只有緩衝區不空時,消費者才能從中取出訊息,否則必須等待。由於緩衝區是臨界資源,它只允許乙個生產者放入訊息,或者乙個消費者從中取出訊息。1) 關係分析。生產者和消費者對緩衝區互斥訪問是互斥關係,同時生產者和消費者又是乙個相互協作的關係,只有生產者生產之後,消費者才能消費,他們也是同步關係。2) 整理思路。這裡比較簡單,只有生產者和消費者兩個程序,正好是這兩個程序存在著互斥關係和同步關係。那麼需要解決的是互斥和同步pv操作的位置。3) 訊號量設定。訊號量mutex作為互斥訊號量,它用於控制互斥訪問緩衝池,互斥訊號量初值為1;訊號量full用於記錄當前緩衝池中「滿」緩衝區數,初值為0。訊號量empty 用於記錄當前緩衝池中「空」緩衝區數,初值為n。
生產者-消費者程序的描述如下:
semaphore mutex=1; //臨界區互斥訊號量
semaphore empty=n; //空閒緩衝區
semaphore full=0; //緩衝區初始化為空
producer ()
}consumer ()
}
該類問題要注意對緩衝區大小為n的處理,當緩衝區中有空時便可對empty變數執行p 操作,一旦取走乙個產品便要執行v操作以釋放空閒區。對empty和full變數的p操作必須放在對mutex的p操作之前。如果生產者程序先執行p(mutex),然後執行p(empty),消費者執行p(mutex),然後執行p(fall),這樣可不可以?答案是否定的。設想生產者程序已經將緩衝區放滿,消費者程序並沒有取產品,即empty = 0,當下次仍然是生產者程序執行時,它先執行p(mutex)封鎖訊號量,再執行p(empty)時將被阻塞,希望消費者取出產品後將其喚醒。輪到消費者程序執行時,它先執行p(mutex),然而由於生產者程序已經封鎖mutex訊號量,消費者程序也會被阻塞,這樣一來生產者、消費者程序都將阻塞,都指望對方喚醒自己,陷入了無休止的等待。同理,如果消費者程序已經將緩衝區取空,即 full = 0,下次如果還是消費者先執行,也會出現類似的死鎖。不過生產者釋放訊號量時,mutex、full先釋放哪乙個無所謂,消費者先釋放mutex還是empty都可以。
下面再看乙個較為複雜的生產者-消費者問題:
桌子上有乙隻盤子,每次只能向其中放入乙個水果。爸爸專向盤子中放蘋果,媽媽專向盤子中放橘子,兒子專等吃盤子中的橘子,女兒專等吃盤子中的蘋果。只有盤子為空時,爸爸或媽媽就可向盤子中放乙個水果;僅當盤子中有自己需要的水果時,兒子或女兒
可以從盤子中取出。1) 關係分析。這裡的關係稍複雜一些,首先由每次只能向其中放入乙隻水果可知爸爸和媽媽是互斥關係。爸爸和女兒、媽媽和兒子是同步關係,而且這兩對程序必須連起來,兒子和女兒之間沒有互斥和同步關係,因為他們是選擇條件執行,不可能併發。
2) 整理思路。這裡有4個程序,實際上可以抽象為兩個生產者和兩個消費者被連線到大小為1的緩衝區上。
圖2-9 程序之間的關係
dad()
}mom()
}son()
}daughter ()
}程序間的關係如圖2-9所示。dad()和daughter()、mam()和son()必須連續執行,正因為如此,也只能在女兒拿走蘋果後,或兒子拿走橘子後才能釋放盤子,即v(plate)操作。
生產者消費者問題
public class producer consumer class godown public godown int num public synchronized void produce int n catch interruptedexception e curr num n syste...
生產者 消費者問題
在學習程序互斥中,有個著名的問題 生產者 消費者問題。這個問題是乙個標準的 著名的同時性程式設計問題的集合 乙個有限緩衝區和兩類執行緒,它們是生產者和消費者,生產者把產品放入緩衝區,相反消費者便是從緩衝區中拿走產品。生產者在緩衝區滿時必須等待,直到緩衝區有空間才繼續生產。消費者在緩衝區空時必 須等待...
生產者 消費者問題
1 程序互斥問題 緩衝區b是臨界資源,程序p和c不能同時對b進行操作,即只能互斥的操作 2 程序同步問題 p不能往 滿 的的緩衝區b放產品,c不能從空的緩衝區獲得產品。當緩衝區滿時,c必須先於p執行,當緩衝區空時,p必須先於c執行 我們給出如下基於記錄型 二元 訊號量機制的解法 10 9 2013 ...