有五個哲學家繞著圓桌坐,每個哲學家面前有一盤面,兩人之間有一支筷子,這樣每個哲學家左右各有一支筷子。哲學家有2個狀態,思考或者拿起筷子吃飯。如果哲學家拿到乙隻筷子,不能吃飯,直到拿到2只才能吃飯,並且一次只能拿起身邊的一支筷子。一旦拿起便不會放下筷子直到把飯吃完,此時才把這雙筷子放回原處。如果,很不幸地,每個哲學家拿起他或她左邊的筷子,那麼就沒有人可以吃到飯了。
該問題涉及linux系統程式設計中經典的執行緒同步問題。
本篇採用訊號量sem來實現。
訊號量sem相當於高階版的mutex,sem_wait()相當於sem–,sem_post相當於sem++。,定義多個訊號量,其中筷子用初始化為1的sem來實現,保證其只能被乙個哲學家拿起,要注意的是,為了防止四個哲學家同時拿起左手或者右手的筷子而導致死鎖,我們需要定義乙個sem陣列,表示最多拿起左手或右手的哲學家數量為4,如此來避免死鎖問題。
最後,利用srand函式和rand函式來保證哲學家拿起左右筷子的隨機性。
#include
#include
#include
#include
#include
#include
#include
#include
#define num 5
//5位哲學家
sem_t max[2]
;//最多允許4位哲學家同時拿起左手或右手筷子(0為右手,1為左手)
sem_t chopsticks[num]
;//訊號量模擬筷子
void
my_err
(const
char
*str)
void
*philosopher
(void
*arg)
else
//拿第一只筷子
sem_wait
(&max[is_first_left]);
sem_wait
(&chopsticks[first]);
if(is_first_left)
printf
("*****第一次,哲學家%d拿起了左手的筷子%d\n"
, i, left)
;else
printf
("*****第一次,哲學家%d拿起了右手的筷子%d\n"
, i, right)
;//第二隻
sem_wait
(&max[
!is_first_left]);
sem_wait
(&chopsticks[second]);
if(is_first_left)
printf
("*****第二次,哲學家%d拿起了右手的筷子%d\n"
, i, right)
;else
printf
("*****第二次,哲學家%d拿起了左手的筷子%d\n"
, i, left)
;//用餐時間
printf
("-----哲學家%d用餐中\n"
, i)
;sleep
(rand()
%5+1
);//放筷子吧
sem_post
(&chopsticks[left]);
sem_post
(&max[1]
);printf
("*****哲學家%d放下了左手的筷子%d\n"
, i, left)
;sem_post
(&chopsticks[right]);
sem_post
(&max[0]
);printf
("*****哲學家%d放下了右手的筷子%d\n"
, i, right);}
}int
main
(int argc,
char
*ar**)
//建立哲學家
for(
int i =
0; i <
5; i++
)//銷毀
for(
int i =
0; i <
5; i++
)for
(int i =
0; i <
2; i++
)sem_destroy
(&max[i]);
return0;
}
哲學家問題
問題描述 有五個哲學家繞著圓桌坐,每個哲學家面前有一盤面,兩人之間有一支筷子,這樣每個哲學家左右各有一支筷子。哲學家有2個狀態,思考或者拿起筷子吃飯。如果哲學家拿到乙隻筷子,不能吃飯,直到拿到2只才能吃飯,並且一次只能拿起身邊的一支筷子。一旦拿起便不會放下筷子直到把飯吃完,此時才把這雙筷子放回原處。...
哲學家就餐問題
本文是哲學家就餐問題在 linux 上的程式實現,與windows 平台的實現類似,程式上稍有不同。philosopherdining.cpp include include include include include include rasutil.h using namespace std ...
哲學家進餐問題
哲學家進餐問題 一 問題 5個哲學家圍坐在乙個圓桌上,每兩個哲學家之間都有乙隻筷子,哲學家平時進行思考,只有當他們飢餓時,才拿起筷子吃飯。規定每個哲學家只能先取其左邊筷子,然後取其右邊筷子,然後才可以吃飯。二 分析 每乙隻筷子都是乙個臨界資源,設定5個互斥訊號量。semaphore stcik 5 ...