1. 程式人生 > >程序的互斥控制_卡車裝水問題

程序的互斥控制_卡車裝水問題

題目:
兩個裝水工人併發的向卡車裝水,一次裝一箱,每輛卡車裝滿20箱即開走.試用基礎訊號量和普通變數實現10輛卡車裝水的虛擬碼.
實現:

訊號量的設定:
名稱		 初值		含義
part         1			車位數
mutex        1			控制工人裝水操作的完整性
empty        0			當前卡車還能裝多少箱水
go           0			當前裝滿水的卡車數

//卡車執行緒
void car()	{
	wait(part);		//排隊進入車位
	for(int i=0;i<20;i++)		//進入後釋放箱子空位
		signal(empty);
	wait(go)
; //等待裝滿水離開 //離開車位 signal(part); } //工人執行緒 void worker(){ while(1) { wait(empty); wait(mutex); //裝水操作 water++; //相對於加在最後,訊號量的獲取與釋放僅加在臨界區才能保證程式良好的併發性 signal(mutex); wait(judge); //判斷是否裝滿,這裡加訊號量是為了防止兩個工人同時進入if並釋放go if(water==20) { water=0; signal(go); } signal(judge); } //main int
main(){ for(int i=0;i<10;i++) car(); //啟動十個車執行緒 worker(); worker(); 啟動兩個搬運工人執行緒 }

總結:
①.當遇到互斥控制的題目時,首先分析在哪裡需要互斥控制,順序控制來決定訊號量的個數,並確定臨界區的範圍.
在本題中:
1.車位只有一個,車有十輛,此處需要互斥.而當車走後,車位才會被釋放(part)
2.每車只能裝20箱,為了防止兩個工人多裝,重複裝,則裝箱操作需要互斥(empty)
3.對於箱數的自增變化需要互斥(mutex)
4.如何讓車在裝滿水之前等待? 可以用wait(go)來阻塞它,讓工人在裝滿水之後發出離開訊號signal(go).
②.當確定訊號量都是什麼之後,根據語義來定義其初始值
1.只有裝滿一輛車後才開走,在此之前只往這輛車裡裝,車位數可知為1
2.每車可裝20箱,則empty在卡車進入時增加20,初值為0,每個裝水工裝水之前申請一個空位.
3.操作互斥變數的訊號量mutex初值置為1
4.車剛到肯定不能走,go訊號量初值為0,由工人來控制何時離開,建立兩程序間的關係.
③.根據訊號量的意義及範圍來在合適的位置釋放資源.如果過早會造成控制的失效,但更多數情況下需要注意的是過晚釋放資源,此時雖然不會造成嚴重的錯誤,但是會使整個程式的併發性降低,並影響程式效率.