問題:
有五個哲學家,
每個哲學家面前有一盤面
每個哲學家左右各有一隻筷子
哲學家有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])
}
}