視頻鏈接:
https://www.bilibili.com/video/BV1YE411D7nH?p=22
一,問題描述:
一張桌子上有5名哲學家,每兩個哲學家之間的桌子上有一根筷子,桌子中間是水煮魚。哲學家們傾注畢生的經歷用於思考和進餐,哲學家在思考時,並不影響他人。只有當哲學家飢餓時,纔會試圖拿起左右兩根筷子(一根,一根地拿起)。如果筷子已經在其他人手上,則需要等待。飢餓的哲學家只有同時拿起兩根筷子纔可以開始進餐,當進餐完畢後,放下筷子繼續思考
二。問題分析:
1,關係分析:系統中有5個哲學家進程,5位哲學家與左右鄰居對中間筷子的訪問是互斥關係。
2,整理思路:這個問題中只有互斥關係,當與之前不同的是,每個哲學家進程需要同時擁有兩個臨界資源纔可以喫飯。如何避免臨界資源分配不當造成的死鎖現象,是哲學家問題的精髓。
3,信號量的設置:定義互斥信號量數組chopsticks[5]={1,1,1,1,1}用於實現對5根筷子的互斥訪問。並對哲學家按0~4編號,哲學家i左邊的筷子編號爲i,右邊的筷子編號爲(i+1)%5
三,具體實現:
問題:如果5個哲學家同時進餐,且在0號哲學家拿起左邊筷子時,發生進程切換到1號哲學家拿起左邊筷子,又發生進程切換...最終5個哲學家都拿起左邊的筷子,每個哲學家都在等待其他哲學家放下筷子,自己不放下筷子的死鎖現象
解決方法一:對哲學家進程添加一些限制條件,比如最多運行四個哲學家同時進餐,這樣就可以保證至少有一個哲學家可以進餐,進餐完成後放下兩根筷子,激活旁邊堵塞的哲學家進程。。。所有哲學家都可以進餐
解決方法二:要求奇數號的哲學家先拿左邊的筷子,然後再拿右邊的筷子,二偶數號哲學家剛好相反。用這種方法可以保證如果相鄰兩個奇偶號哲學家都想喫飯,那麼自會有其中一個哲學家拿起第一隻筷子,另外一個沒有拿起筷子的哲學家進程會直接堵塞,這就避免了哲學家佔有一隻筷子後等待另一隻的情況、
解決方法三:僅當一個哲學家左右兩邊筷子都可以使用時才允許其進餐。
方法三的代碼實現:
semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex=1; //互斥的訪問筷子
Pi(){//第i個進程此處共有5個進程
while(1){
P(mutex);
P(chopstick[i]);//拿左邊的筷子
P(chopstick[(i+1)%5)]);//拿右邊的筷子
V(mutex);
喫飯...
V(chopstick[i]);//放左邊的筷子
V(chopstick[(i+1)%5)]);//放右邊的筷子
思考...
}
}
假設1號哲學家拿起了,左邊1號筷子和右邊2號筷子,就會對兩隻筷子執行P操作使得其他進程不能對他們訪問,如果1號哲學家在喫飯時,發生了進程切換2號哲學家,它在拿起左邊2號筷子時就會被堵塞,並不會拿起3號筷子佔用資源。