程序的互斥控制_卡車裝水問題
阿新 • • 發佈:2018-11-25
題目:
兩個裝水工人併發的向卡車裝水,一次裝一箱,每輛卡車裝滿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,由工人來控制何時離開,建立兩程序間的關係.
③.根據訊號量的意義及範圍來在合適的位置釋放資源.如果過早會造成控制的失效,但更多數情況下需要注意的是過晚釋放資源,此時雖然不會造成嚴重的錯誤,但是會使整個程式的併發性降低,並影響程式效率.