經典同步問題一 生產者和消費者問題

2021-10-05 03:15:58 字數 2345 閱讀 1909

系列同步問題:

經典同步問題一——生產者和消費者問題

經典同步問題二——哲學家進餐問題

經典同步問題三——讀者寫者問題

不懂得結構型訊號量的小夥伴可參考下面博文,之後再閱讀本博文,更易於理解

乙個或多個生產者產生資料並放在緩衝區中,每次乙個。

乙個或多個消費者從緩衝區取資料項並消費,每次乙個。

條件:1 在任意時間只能乙個生產者或消費者訪問緩衝區——互斥

2 保證生產者不能向滿緩衝區中放產品

3 保證消費者不能從空緩衝區中取產品

q:為什麼緩衝區要互斥?

a:舉例說明:環形緩衝區,用in指標指向將要放產品的緩衝區下標,out指標指向將要取出產品的緩衝區下標。對應一下put和take操作:

put

(a)take()

如果有兩個程序p1和p2,在p1將a寫入buffer[in]中後,in還未來得及改變的時候,p2又將b寫入buffer[in],則出錯。因此緩衝區需要互斥訪問。

不考慮條件的話,問題如下:

void

producer()

}void

consumer()

}

考慮實現互斥條件,只需設定訊號量s.value=1,並在緩衝區操作前加上wait(a),緩衝區操作後加入signal(a)。

semaphore s.value =1;

void

producer()

}void

consumer()

}

考慮實現緩衝區為空時不能取產品,則必須在至少乙個生產者實現put(a)操作後,才能執行take(a)操作。只需設定訊號量n.value=0,在put之後執行signal(n),在take之前執行wait(n)。此時n.value彷彿乙個計數器,記錄著緩衝區產品的個數,只要這個值大於零,消費者就可以消費,而且在消費者消費之前,n.value要減1,即take之前要先執行wait(n)。

這裡有兩個問題,為什麼signal(n)要放在signal(s)之後,為什麼wait(n)要放在wait(s)之前。

先說第乙個問題,為什麼signal(n)要放在signal(s)之後?

如果交換signal(n)和signal(s)的位置,先執行signal(n),後執行signal(s),則此時signal(n)是在臨界區內執行。此時可能出現以下情況:如果乙個消費者因執行wait(n)而正在等待,則此時執行signal(n)將會被喚醒。而此時生產者還沒有從臨界區出來,則消費者會因為執行wait(s)而繼續被阻塞。由此可見,交換signal(s)和signal(n)不會出錯,但是從優化角度來說,signal(s)在前更好。

再說第二個問題,為什麼wait(s)要放在wait(n)之後?

如果交換wait(s)和wait(n)的位置,先執行wait(s),後執行wait(n),則此時我們把wait(n)放入了臨界區中。我們知道wait操作在某種情況下會導致程序進入等待狀態。現在假設我們在初始情況下先執行consumer(),執行wait(s)時,由於s.value的初值是1,則可以進入臨界區,再執行wait(n)時,由於n.value=0,則會導致程序阻塞。而我們發現,能夠喚醒wait(n)的signal(n)操作,必須在使用臨界區之後才能執行,那麼這種情況下,臨界區被阻塞,生產者永遠不可能進入臨界區,也就永遠不可能執行signal(n),阻塞將一直存在,即產生了死鎖。這種次序的交換會引起錯誤。

semaphore s.value =1;

semaphore n.value =0;

void

producer()

}void

consumer()

}

考慮實現緩衝區滿時不能再放入產品。可以設定乙個訊號量e.value=max,每向緩衝區放1個產品,e.value減1,當值減為0,說明不能再放入產品。也就是要在put前面加上wait(e)操作。同理,每消費乙個產品,e.value加1。即在take之後加上signal(e)操作。

這裡同樣存在上文所說的兩個問題。即signal(e)為什麼要在signal(s)之後,wait(e)為什麼要在wait(s)之前。原因也如上文所述。同樣交換signal不會出錯,交換wait會產生死鎖。

semaphore e.value = max;

semaphore s.value =1;

semaphore n.value =0;

void

producer()

}void

consumer()

}

程序間同步互斥經典問題 一 生產者 消費者問題

生產者 消費者問題,也叫做快取繫結問題 bounded buffer 是乙個多程序同步問題。要避免多個生產商競爭乙個空位的情況。要避免生產商和消費者同時睡覺,造成死鎖 要避免多個消費者競爭同一段資料的情況 首先考慮生產商,在多個生產商和多個消費者同時執行的情況下 2.每乙個生產商在執行操作前申請互斥...

6 1 生產者 消費者問題

在多執行緒程式中,執行緒之間通常存在分工。在一種常見模式中,一些執行緒是生產者,一些是消費者。需要強制執行幾個同步約束才能使此系統正常工作 在緩衝區中新增或刪除專案時,緩衝區處於不一致狀態。因此,執行緒必須具有對緩衝區的獨佔訪問許可權。如果消費者執行緒在緩衝區為空時到達,則會阻塞,直到生產者新增新專...

5 12 生產者和消費者

一 生產者和消費者之間的關係 1 生產者將生產出來的資訊不斷存入乙個區域內,消費者將資訊從該區域內不斷讀取出來 生產者錄入資訊 消費者讀取資訊 例 電影票 public class movie public void setname string name public string getinfo...