1. 程式人生 > >經典程序的同步問題1

經典程序的同步問題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;當他們在試圖去拿右邊的筷子時,都將因為無筷子可拿而無限期等待。

  1. 至多隻允許有四位哲學家同事去拿左邊的筷子,

  2. 僅當哲學家的左、右兩隻筷子均可用時,才允許他拿起筷子進餐。

  3. 規定奇數號哲學家先拿他左邊的筷子,然後再去拿右邊的筷子;而偶數號哲學家則相反
    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]