經典IPC問題(哲學家進餐)

問題:
有五個哲學家,
每個哲學家面前有一盤面
每個哲學家左右各有一隻筷子
哲學家有2個狀態,思考或者拿起筷子吃飯。
如果哲學家拿到一隻筷子,不能吃飯,拿到2只才能吃飯。

一,考慮第一種自然情況:
解法:所有哲學家拿起一隻筷子,再拿旁邊的一隻,如果拿不到就等,等到可以拿了再拿
問題:所有哲學家都拿起一隻筷子,那就都吃不到飯,就是死鎖
二,解決上邊的問題
解法:每個哲學家先拿左邊的筷子,再拿右邊的筷子,如果拿不到右邊的筷子,就放棄左邊的筷子,等待一段時間再試
問題:試想所有哲學家同時拿起筷子,同時放棄,再同時拿起,同時放棄。。如此就進入了另外一種死循環
三,解決上邊的問題:
解法:在上邊的情況下,每次等待的時間變成隨機一段時間,這樣基本能解決問題,例如以太網的工作方式就是這樣
問題:再極少數情況下,還是會出現衝突,在一些要求較高的情況,例如核電站的安全系統,這種情況試不允許出現的
四,最終解決方法:
解法:使用多個互斥信號量,每個哲學家在想取筷子前先執行mutex,然後判斷一下左右的筷子是否有人用,如果沒有就拿起筷子,否則就不拿筷子
實現程序:
#define N 5
#define Left (i+N-1)%N
#define Right (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
typedef int semaphore;
int state(N);
semapore mutex =1;
semaphore s(N);

void philosopher(int i){
 while(TRUE){
  think();
  take_forks(i);
  eat();
  put_forks(i);
 }
}
void tak_forks(int i){
 down(&mutex);
 state(i)=HUNGRY;
 test(i);
 up(&mutex);
 down(&s[i]);
}
void put_forks(int i){
 down(&mutex);
 state(i)=THINK;
 test(LEFT);
 test(RIGHT);
 up(&mutex);
}
void test(i){
 if(state(i)==HUNGRY && state(LEFT)!=EATING && state(RIGHT)!=EATING){
  state(i)=EATING;
  up(&s[i])
 }
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章