二、對第乙個方案的改正
背景描述
有五個哲學家,他們的生活方式是交替地進行思考和進餐,哲學家們共用一張圓桌,分別坐在周圍的五張椅子上,在圓桌上有五個碗和五支筷子,平時哲學家進行思考,飢餓時便試圖取其左、右最靠近他的筷子,只有在他拿到兩支筷子時才能進餐,該哲學家進餐完畢後,放下左右兩隻筷子又繼續思考。
約束條件:
(1)只有拿到兩隻筷子時,哲學家才能吃飯。
(2)如果筷子已被別人拿走,則必須等別人吃完之後才能拿到筷子。
(3)任一哲學家在自己未拿到兩隻筷子吃完飯前,不會放下手中已經拿到的筷子。
我們要實現的是每個哲學家都有機會拿到左右兩把叉子進行用餐,那麼,可以明確的是叉子成為相鄰哲學家進餐的競爭條件。接下來,我們通過一些操作實現哲學家間取叉子的同步而不產生死鎖。
方案描述
如上圖,對所有哲學家和叉子進行編號,每個哲學家右手的叉子的編號與哲學家編號相同。進餐時,每個哲學家先取得右手的叉子,再取得左手的叉子,方可開始進餐。
下圖是對上述方案的流程描述
到這,不妨思考幾秒鐘,這個方案會產生什麼問題呢?
好了,揭曉漏洞:
這種實現是有可能產生死鎖的,即所有哲學家都拿著右手邊的叉子,都在等待左手邊的叉子,於是每個人都幹等著,誰都吃不到飯。
方案**
#include
#include
#include
#include
#include
#include
#define num 5
int eaters =0;
//-------------------一些訊號量----------------
sem_t sem_fork[num]
;sem_t sem_eaters;
void
sem_mutex_init()
if(sem_init
(&sem_eaters,0,
1)==-
1)return;}
void
philosopher()
}int
main
(void)}
sem_mutex_init()
;for
(i =
0; i < num;
++i)
return0;
}
方案描述
此方案和第乙個方案大同小異。那麼,改正方案通過「單雙號限流」避免死鎖:雙號執行緒先拿右手邊叉子,拿左手邊叉子;單號執行緒先拿左手邊叉子再拿右手邊叉子。
腦補一下,這樣就不會產生死鎖了,對吧
方案**
**和上乙個方案的區別就在philosopher函式裡對執行緒單雙號進行了區別對待
#include
#include
#include
#include
#include
#include
#define num 5
int eaters =0;
//-------------------一些訊號量----------------
sem_t sem_fork[num]
;sem_t sem_eaters;
void
sem_mutex_init()
if(sem_init
(&sem_eaters,0,
1)==-
1)return;}
void
philosopher()
else}}
intmain
(void)}
sem_mutex_init()
;for
(i =
0; i < num;
++i)
return0;
}
筆者才疏學淺,若同學們有更好的想法請不吝賜教,一起**哈!首次編輯 2020-4-26 23:10:58 作業系統執行緒同步之哲學家進餐問題
五個哲學家,五隻筷子,只有獲得一雙筷子之後才能就餐,就有可能出現這種情況 每個哲學家都獲得了乙隻筷子,卡死在那個地方。1 有乙個服務生來負責避免死鎖 2 哲學家在拿筷子的時候,確保左右都有筷子才同時拿起左右兩隻筷子 3 規定拿筷子的方式 給筷子編號,先拿號碼小的筷子 class chopsticks...
經典程序的同步問題之 哲學家進餐
哲學家進餐問題描述 由dijkstra提出並解決哲學家進餐問題 the dinning philosophers problem 是經典的同步問題。該問題是描述有五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在桌子上有五個碗和五隻筷子,他們的生活方式是交替的進行思考和進餐。平時,乙個哲學家進行思...
程序同步 互斥 哲學家進餐問題
1 問題描述 一張圓桌上有5名哲學家,沒兩個哲學家之間有一根筷子,桌子中間由一碗公尺飯。當哲學家飢餓時會試圖分別拿起左右兩根筷子,如果筷子已在他人手上則需等待。飢餓的哲學家只有拿起兩根筷子才能進餐,吃完後才能放下筷子。2 問題分析 對哲學家分別編號0,1,2,3,4,對筷子編號0,1,2,3,4。i...