問題描述

哲學家就餐問題
方案一:
#define N 5 //哲學家個數(shù)
semaphore fork[5]; //信號量初始值為1
void philosopher(int i){ //哲學家編號:0-4
while(true){
think(); //哲學家在思考
P(fork[i]); //去拿左邊的叉子
P(fork[(i+1)%N]); //去拿右邊的叉子
eat(); //吃面條中
V(fork[i]); //放下左邊的叉子
V(fork[(i+1)%N]); //放下右邊的叉子
}
}
該方案能滿足大多數(shù)情況,但仍存在這么個情況,5個哲學家同時拿起左邊的刀叉,那么會導致沒有人可以吃面條,導致死鎖。
方案二:使用一個信號量,保證只有一個人就餐
#define N 5 //哲學家個數(shù)
semaphore fork[5]; //信號量初始值為1
semaphore mutex; //互斥信號量,初始值為1
void philosopher(int i){ //哲學家編號:0-4
while(true){
think(); //哲學家在思考
P(mutex); //進入臨界區(qū)
P(fork[i]); //去拿左邊的叉子
P(fork[(i+1)%N]); //去拿右邊的叉子
eat(); //吃面條中
V(fork[i]); //放下左邊的叉子
V(fork[(i+1)%N]); //放下右邊的叉子
V(mutex); //退出臨界區(qū)
}
}
該方案是正確的,不存在死鎖,但效率很低。
方案三:設置哲學家拿刀叉的時候存在差異,分奇偶來確定拿刀叉的方式
#define N 5 //哲學家個數(shù)
semaphore fork[5]; //信號量初始值為1
void philosopher(int i){ //哲學家編號:0-4
while(true){
think(); //哲學家在思考
if (i % 2 == 0){
P(fork[i]); //去拿左邊的叉子
P(fork[(i+1)%N]); //去拿右邊的叉子
} else {
P(fork[(i+1)%N]); //去拿右邊的叉子
P(fork[i]); //去拿左邊的叉子
}
eat(); //吃面條中
V(fork[i]); //放下左邊的叉子
V(fork[(i+1)%N]); //放下右邊的叉子
}
}
注意:這里只需要對P操作進行分類,對V操作不需要進行分類,因為V操作是不會阻塞的。