經典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])
?}
}
posted on 2006-09-20 21:30 dreamstone 閱讀(863) 評論(0) 編輯 收藏 所屬分類: 基礎