經典程序的同步問題1
生產者-消費者問題
假設在生產者和消費者之間的公用緩衝池中具有n個緩衝區,這時可利用互斥訊號量mutex實現諸程序對緩衝池的互斥使用;利用empty和full分別表示緩衝池中空緩衝區和滿緩衝區的數量。
int in=0,out=0; item buffer[n]; semaphore mutex=1,empty=n,full=0; void proceducer(){//生產者程序 do{ producer an item nextp; ... wait(empty);//空間減一,若小於零則阻塞 wait(mutex);//生產消費互斥 buffer[in]=nextp;//公共緩衝池指標移動 in=(in+1)%n; signal(mutex); signal(full);//慢緩衝區+1 }while(TRUE); } void consumer(){//消費者程序 do{ wait(full);//滿緩衝區-1 full<0時阻塞程序 wait(mutex);//互斥 nextc=buffer[out]; out=(out+1)%n; signal(mutex); signal(empty); consumer the item in nextc; ... }while(true); } void main(){ cobegin proceducer(); consumer(); coend }
注意:
①在每個程式中用於實現互斥的wait(mutex)和signal(mutex)必須成對的出現。
②對資源訊號量empty和full的wait和signal操作,同樣需要成對出現。但它們分別處於不同的程式中
2.利用AND訊號量解決生產者-消費者問題
int in=0,out=0; item buffer[n]; semaphore mutex=1,empty=n,full=0; void proceducer(){ do{ producer an item nextp; ... Swait(empty,mutex); buffer[in]=nextp; in=(in+1)%n; Ssignal(mutex,full); }while(TRUE); } void consumer(){ do{ Swait(full,mutex); nextc=buffer[out]; out=(out+1)%n; Ssignal(mutex,empty); consumer the item in nextc; ... }while(TRUE); }
哲學家進餐問題
五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在圓桌上有五個碗和五支筷子,他們的生活方式是交替的進行思考和進餐。平時,一個哲學家進行思考,飢餓時便試圖去用其左右最靠近他的筷子,只有在談到兩隻筷子時才能進餐。進餐畢,放下筷子繼續思考。
1.利用記錄型訊號量解決哲學家進餐問題
筷子是臨界資源,為了實現對筷子的互斥使用,可以用一個訊號量表示一隻筷子,有這五個訊號量構成訊號量陣列。
semaphore chopstick[5]={1,1,1,1,1};//所有訊號量均被初始化為1,第i為哲學家的活動可描述為: do{ wait(chopstick[i]);//拿左邊筷子 wait(chopstick[(i+1)%5]);//拿右邊筷子 ... //eat ... signal(chopstick[i]);//放左邊筷子 signal(chopstick[(i+1)%5]);//放右邊筷子 ... //think ... }while(true); 死鎖問題:五位哲學家同
時飢餓而各自拿起左邊的筷子時,就會使五個訊號量均為0;當他們在試圖去拿右邊的筷子時,都將因為無筷子可拿而無限期等待。
-
至多隻允許有四位哲學家同事去拿左邊的筷子,
-
僅當哲學家的左、右兩隻筷子均可用時,才允許他拿起筷子進餐。
-
規定奇數號哲學家先拿他左邊的筷子,然後再去拿右邊的筷子;而偶數號哲學家則相反
2.利用AND訊號量機制解決哲學家進餐問題semaphore chopstick[5]={1,1,1,1,1};
do{
…
//think
…
Sswait(chopstick(i+1)%5],chopstick[i]);
…
//eat
…
Ssignal(chopstick[(i+1)%5],chopstick[i]);
)while[true]