五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在桌子上有五隻碗和五隻筷子,他們的生活方式是交替地進行思考和進餐。平時,乙個哲學家進行思考,飢餓時便試圖取用其左右最靠近他的筷子,只有在他拿到兩隻筷子時才能進餐。進餐畢,放下筷子繼續思考。
在這裡插入描述
分析:放在桌子上的筷子是臨界資源,在一段時間內只允許一位哲學家使用,為了實現對筷子的互斥訪問,可以用乙個訊號量表示筷子,由這五個訊號量構成訊號量陣列。
semaphore chopstick[5]
=;while
(true
)
的**可以保證不會有兩個相鄰的哲學家同時進餐,但卻可能引起死鎖的情況。假如五位哲學家同時飢餓而都拿起的左邊的筷子,就會使五個訊號量chopstick都為0,當他們試圖去拿右手邊的筷子時,都將無筷子而陷入無限期的等待。
為避免死鎖,可以使用以下三種策略:
策略一:至多只允許四個哲學家同時進餐,以保證至少有乙個哲學家能夠進餐,最終總會釋放出他所使用過的兩支筷子,從而可使更多的哲學家進餐。定義訊號量count,只允許4個哲學家同時進餐,這樣就能保證至少有乙個哲學家可以就餐。
semaphore chopstick[5]
=;semaphore count=4;
// 設定乙個count,最多有四個哲學家可以進來
void
philosopher
(int i)
}
策略二:僅當哲學家的左右兩支筷子都可用時,才允許他拿起筷子進餐。可以利用and 型訊號量機制實現,也可以利用訊號量的保護機制實現。利用訊號量的保護機制實現的思想是通過記錄型訊號量mutex對取左側和右側筷子的操作進行保護,使之成為乙個原子操作,這樣可以防止死鎖的出現。描述如下:
用記錄型訊號量實現:
semaphore mutex =1;
// 這個過程需要判斷兩根筷子是否可用,並保護起來
semaphore chopstick[5]
=;void
philosopher
(int i)
}
用and型訊號量實現:
semaphore chopstick[5]
=;dowhile
(true
)
策略三:規定奇數號的哲學家先拿起他左邊的筷子,然後再去拿他右邊的筷子;而偶數號的哲學家則先拿起他右邊的筷子,然後再去拿他左邊的筷子。按此規定,將是1、2號哲學家競爭1號筷子,3、4號哲學家競爭3號筷子。即五個哲學家都競爭奇數號筷子,獲得後,再去競爭偶數號筷子,最後總會有乙個哲學家能獲得兩支筷子而進餐。
semaphore chopstick[5]
=;void
philosopher
(int i)
else
//奇數哲學家,先左後右。
}}
哲學家用餐問題
哲學家用餐問題,怎麼樣保證沒有死鎖,最直接的乙個方案就是要保證,每乙個哲學家在拿筷子的時候,左右兩邊都能拿到,才去拿,如果不能保證那就乙個筷子都不拿。對與這個問題的實現,可以設定五個訊號量,標識筷子是否可以拿。具體 如下。public static class person implements r...
哲學家用餐問題
哲學家用餐問題,5位哲學家坐在圓桌旁,每對哲學家之間只有一根筷子。如果乙個哲學家可以拿起他旁邊的兩根筷子,他就可以吃東西。一根筷子可以由其相鄰的任何乙個哲學家拿起,但不能同時被兩個哲學家拿起。如果遵循乙個簡單的規則,就可以避免死鎖 讓所有執行緒以相同的順序宣告並釋放其鎖。這樣,您永遠不會陷入可能發生...
linux多執行緒 3 哲學家用餐 mutex實現
ref 5跟筷子,5個哲學家,哲學家要吃飯,自然要兩根筷子,這樣就出現資源爭用的情況。哲學家只能用左邊和右邊的筷子,兩根筷子備齊才能吃飯!使用mutex的話,就是每個筷子乙個mutex,需要5個mutex,哲學家先lock左邊的筷子,如果有人已經在用那根筷子了,那就等著,不然左邊的筷子就拿到手了,然...