1、明肯定義
要理解生產消費者問題,首先應弄清PV操做的含義:PV操做是由P操做原語和V操做原語組成(原語是不可中斷的過程),對信號量進行操做,具體定義以下:動畫
P(S):①將信號量S的值減1,即S=S-1;.net
②若是S ,則該進程繼續執行;不然該進程置爲等待狀態,排入等待隊列。指針
V(S):①將信號量S的值加1,即S=S+1;blog
②若是S>0,則該進程繼續執行;不然釋放隊列中第一個等待信號量的進程。隊列
這只是書本的定義,對於這部份內容,老師先不要急於解釋上面的程序流程,而是應該讓學生首先知道P操做與V操做到底有什麼做用。進程
P操做至關於申請資源,而V操做至關於釋放資源。因此要學生記住如下幾個關鍵字:資源
P操做-----à申請資源同步
V操做----à釋放資源產品
2、形象啓發
爲此舉兩個生活中的例子:程序
例一:在公共電話廳打電話
公共電話廳裏有多個電話,如某人要打電話,首先要進行申請,看是否有電話空閒,如有,則可使用電話,若是電話亭裏全部電話都有人正在使用,那後來的人只有排隊等候。當某人用完電話後,則有空電話騰出,正在排隊的第一我的就可使用電話。這就至關於PV操做:
某人要打電話,首先要進行申請,至關於執行一次P操做,申請一個可用資源(電話);
某人用完電話,則有空電話騰出,至關於執行一次V操做,釋放一個可用資源(電話)。
在多媒體課件中,這部份內容充分經過動畫效果,演示整個申請電話資源(P操做)與釋放電話資源(V操做)的過程,同時顯示當前可用的資源個數(電話個數)。課件直觀生動,一目瞭然,學生很是容易接受,而且理解深入。
3、分層解剖
在理解了PV操做的的含義後,就必須講解利用PV操做能夠實現進程的兩種狀況:互斥和同步。根據互斥和同步不一樣的特色,就有利用PV操做實現互斥與同步相對固定的結構模式。這裏就不詳細講解了。但生產者-消費者問題是一個有表明性的進程同步問題,要學生透徹理解並不容易。可是若是咱們將問題細分紅三種狀況進行講解,理解難度將大大下降。
1)一個生產者,一個消費者,公用一個緩衝區。
能夠做如下比喻:將一個生產者比喻爲一個生產廠家,如伊利牛奶廠家,而一個消費者,比喻是學生小明,而一個緩衝區則比喻成一間好又多。第一種狀況,能夠理解成伊利牛奶生產廠家生產一盒牛奶,把它放在好又多一分店進行銷售,而小明則能夠從那裏買到這盒牛奶。只有當廠家把牛奶放在商店裏面後,小明才能夠從商店裏買到牛奶。因此很明顯這是最簡單的同步問題。
解題以下:
定義兩個同步信號量:
empty——表示緩衝區是否爲空,初值爲1。
full——表示緩衝區中是否爲滿,初值爲0。
生產者進程
while(TRUE){
生產一個產品;
P(empty);
產品送往Buffer;
V(full);
}
消費者進程
while(TRUE){
P(full);
從Buffer取出一個產品;
V(empty);
消費該產品;
2)一個生產者,一個消費者,公用n個環形緩衝區。
第二種狀況能夠理解爲伊利牛奶生產廠家能夠生產好多牛奶,並將它們放在多個好又多分店進行銷售,而小明能夠從任一間好又多分店中購買到牛奶。一樣,只有當廠家把牛奶放在某一分店裏,小明才能夠從這間分店中買到牛奶。不一樣於第一種狀況的是,第二種狀況有N個分店(即N個緩衝區造成一個環形緩衝區),因此要利用指針,要求廠家必須按必定的順序將商品依次放到每個分店中。緩衝區的指向則經過模運算獲得。
解題以下:
定義兩個同步信號量:
empty——表示緩衝區是否爲空,初值爲n。
full——表示緩衝區中是否爲滿,初值爲0。
設緩衝區的編號爲1~n-1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指針,指向下一個可用的緩衝區。
生產者進程
while(TRUE){
生產一個產品;
P(empty);
產品送往buffer(in);
in=(in+1)mod n;
V(full);
}
消費者進程
while(TRUE){
P(full);
從buffer(out)中取出產品;
out=(out+1)mod n;
V(empty);
消費該產品;
}
3)一組生產者,一組消費者,公用n個環形緩衝區
第三種狀況,能夠理解成有多間牛奶生產廠家,如蒙牛,達能,光明等,消費者也不僅小明一人,有許許多多消費者。不一樣的牛奶生產廠家生產的商品能夠放在不一樣的好又多分店中銷售,而不一樣的消費者能夠去不一樣的分店中購買。當某一分店已放滿某個廠家的商品時,下一個廠家只能把商品放在下一間分店。因此在這種狀況中,生產者與消費者存在同步關係,並且各個生產者之間、各個消費者之間存在互斥關係,他們必須互斥地訪問緩衝區。
解題以下:
定義四個信號量:
empty——表示緩衝區是否爲空,初值爲n。
full——表示緩衝區中是否爲滿,初值爲0。
mutex1——生產者之間的互斥信號量,初值爲1。
mutex2——消費者之間的互斥信號量,初值爲1。
設緩衝區的編號爲1~n-1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指針,指向下一個可用的緩衝區。
生產者進程
while(TRUE){
生產一個產品;
P(empty);
P(mutex1);
產品送往buffer(in);
in=(in+1)mod n;
V(mutex1);
V(full);
}
消費者進程
while(TRUE){
P(full);
P(mutex2);
從buffer(out)中取出產品;
out=(out+1)mod n;
V(mutex2);
V(empty);