生產者 消費者問題

2021-07-11 08:37:37 字數 2430 閱讀 3501

作為作業系統最精華的部分,生產者消費者問題無疑是經典問題中的經典問題。

今天終於有空能好好研究一下這類問題了,不對之處還望大家指正。

首先,講解經典的生產者消費者問題。

問題描述:一組生產者程序和消費者程序共享乙個初始為空,大小為n的緩衝區。只有當緩衝區沒滿的時候,生產者才能將訊息放進去。同理,只有當緩衝區不空的時候,消費者才能從中取訊息,否則必須等待。由於緩衝區是臨界資源,它只允許乙個生產者放入訊息,也只允許乙個消費者拿出訊息。這裡我再解釋一下,意思是,同乙個時刻只能是乙個生產者或者乙個消費者操作緩衝區,禁止一下情況:多個生產者或者多個消費者操作緩衝區,同樣,乙個生產者和乙個消費者同時操作也是禁止的。

分析:首先,生產者之間,消費者之間是互斥的關係,同時生產者消費者之間又是協同的關係,屬於程序同步。

其次,設定訊號量,我們知道訊號量個數等於資源數,我們用empty=n表示緩衝區空的緩衝區數目,用full=0表示緩衝區滿的緩衝區數目。同時,還要乙個訊號量mutex來實現,諸程序對緩衝區的互斥訪問。

int in = 0,out = 0;  //緩衝區 生產和消費初始的指標

item buffer[n]; //表示n個緩衝區

semaphore mutex = 1; //臨界區互斥訊號量

semaphore empty = n; //空閒緩衝區為n

semaphore full = 0; //緩衝區初始化為空

void producer()

while(true);

}void consumer()while(true);

}void main()

再補充一下,wait操作和signal操作

void wait(semaphore *s)

void signal(semaphore *s)

//value的絕對值表示當前程序阻塞數目

當然這只是最基本的情況,生產者消費者問題有很多變種,要是這麼簡單我也不會發這篇博文了。

變種1: 調整生產者或者消費者的wait操作順序,是否對結果有影響?

這裡我把生產者消費者混在一起,是因為它們之間是類似的情況。

結果是有影響。因為順序一旦調整(假設調整的是生產者的wait順序),當緩衝區滿的時候,下乙個時刻如果還是生產者搶到cpu的資源,首先執行wait(mutex)操作,將訊號量封鎖,然後執行wait(empty)操作,發現沒有空緩衝區了,生產者程序就進入阻塞狀態,下乙個時刻若是消費者搶到cpu資源,發現mutex值為0,進入阻塞。這樣一來生產者消費者都期待對方喚醒自己,結果陷入了無休止的等待。消費者調整順序與此情況類似。

變種2:調整生產者或者消費者的signal操作順序,是否對結果有影響?

結果是沒有影響。因為喚醒某個程序是不會引起阻塞的。

變種3: 單生產者,單消費者,多緩衝區時,怎樣設定訊號量?

這裡因為生產者消費者只有乙個,不存在生產者之間和消費者之間的互斥,只要設定兩個訊號量empty=n,full=0

因為這裡多緩衝區這個條件是沒有變化的。有人說了,不設定mutex,會導致消費者生產者同時操作緩衝區。這到底要不要緊呢?

答案是不要緊,因為in,out指標表明了,生產者和消費者同時操作緩衝區內一前一後指標所指向的數,也就是說,生產者生產的資料放在隊尾,消費者消費的資料是隊頭的資料,怎麼會衝突呢?

變種4: 多生產者多消費,單緩衝區

很多人剛開始認為此型別只要設定乙個mutex就可以了,答案是不可以的。為什麼?因為如果生產者生產了乙個資料,消費者沒有消費,緊接著生產者又生產了,因為只有乙個緩衝區,所以資料就被覆蓋了。正確的方案是 設定兩個訊號量empty = 1,full = 0可以保證生產者生產乙個資料,然後只有消費者才能消費,這樣迴圈下去。其實這種情況和輸入列印有點類似。

變種5: 單生產者單消費者,單緩衝區

此種情況 和 變種4是一致的。 對於單緩衝區,也有空 和 滿 兩種情況。也必須按順序執行,不能有被覆蓋的資料。

變種6:允許生產者寫時,消費者可讀

這種情況下就不能設定乙個mutex了,因為生產者和消費者可以同時訪問緩衝區,解決方案是 給生產者消費者分別設定mutexa,mutexb,使它們各自互斥,但是生產者和消費者之間不互斥

變種7:緩衝區無限大

這種情況下,就不要設定empty訊號量了,只用乙個full表示緩衝區滿的個數,這個個數表示的是緩衝區內資料的個數

變種8: 每個訊息都要每個消費者消費一次

這種情況下,我舉乙個例子來說明。

假設有生產者a,消費者b,c,d,它們之間共享乙個緩衝區,a生產之後,消費者b,c,d都要消費一次,然後a才能再生產。

這裡,我設定了三個互斥量mutexb,mutexc,mutexd 分別於a互斥,初值都為1,再設定empty=1,full=0

生產者程序裡執行三個wait(mutexa),wait(mutexb),wait(mutexc)之後,確保三個消費者都消費一次之後,再進行生產操作。

生產者消費者問題

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 ...