PV原語解決哲學家喫通心麪問題之個人觀點

PV原語解決哲學家喫通心麪問題之個人觀點
PV信號量有互斥信號量,整型信號量還有記錄型信號量以及多信號量(如AND信號量、一般信號量集),我們這裏採用互斥信號量和整型信號量來解決哲學家喫通心麪問題。
我們先用代碼(可能不滿足具體的某種編程語言規範)來描述哲學家吃麪問題的場景。(自然語言描述是五個哲學家圍坐在一張圓桌旁,桌子中央一盤通心麪(面假設無限),每個人面前有一隻空盤,每兩個人之間放一把叉子。爲了吃麪,每個哲學家都必須獲得兩把叉子,且只能從自己左邊或右邊取。則叉子就相當於臨界資源,我們爲每把叉子設置一個互斥信號量Si(i=0,1,2,3,4),初值均爲1,表示均爲被使用)。
  var fork:array[0...4] of mutex;
forki := 1;
cobegin
process Pi //i=0...4
begin
while(true){
思考;
P(fork[i]);
P(fork[i+1]mod5);
喫通心麪;
V(fork[i]);
V(fork[i+1]mod5);
}
end;
coend

哲學家問題要解決的其實是死鎖問題:
在上述情景下,假如五個哲學家同時拿起右手邊的叉子,那麼五個人都將等待相鄰哲學家手中的叉子,出現“死鎖”。
要解決這種死鎖,有很多方法,我採用的是:至多允許四個哲學家同時吃麪。即我增加一個整型信號量,初值設爲4,用於記錄某一時刻正在吃麪的哲學家總數。
則有如下代碼:

 var fork:array[0...4] of mutex;
int count: semaphore;
forki := 1;
count:=4;
cobegin
process Pi //i=0...4
begin
while(true){
思考;
P(count); //在吃麪前先check下當前吃麪的哲學家總數,如果爲4,則等待
P(fork[i]);
P(fork[i+1]mod5);
喫通心麪;
V(fork[i]);
V(fork[i+1]mod5);
V(count);
}
end;
coend

上述就解決了哲學家吃麪的問題。
具體的採用某種編程語言解決哲學家吃麪問題(如JAVA)時,我們可以採用如下辦法。
PV 原語由於是不可被中斷的“原子操作”。
我們可以借鑑JAVA中的synchronized關鍵詞。
拿互斥信號量來說:
我們可以這樣定義它對應的P、V原語操作
 boolean binary_semaphore;   //定義互斥信號量
synchronized void p(boolean binary_semaphore){
while(!binary_semaphore){ //信號量被佔用,此時空等 }
binary_semaphore = FALSE; //取得信號量,並將信號量置爲佔用標識
}
synchronized void v(boolean binary_semphore){
binary_semaphore = TRUE; //歸還信號量,重新置信號量爲可用標識
}

其他單信號量的PV原語操作類似。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章