问题描述
方案一:
#define N 5 //哲学家个数
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]); //放下右边的叉子
}
}
该方案能满足大多数情况,但仍存在这么个情况,5个哲学家同时拿起左边的刀叉,那么会导致没有人可以吃面条,导致死锁。
方案二:使用一个信号量,保证只有一个人就餐
#define N 5 //哲学家个数
semaphore fork[5]; //信号量初始值为1
semaphore mutex; //互斥信号量,初始值为1
void philosopher(int i){ //哲学家编号:0-4
while(true){
think(); //哲学家在思考
P(mutex); //进入临界区
P(fork[i]); //去拿左边的叉子
P(fork[(i+1)%N]); //去拿右边的叉子
eat(); //吃面条中
V(fork[i]); //放下左边的叉子
V(fork[(i+1)%N]); //放下右边的叉子
V(mutex); //退出临界区
}
}
该方案是正确的,不存在死锁,但效率很低。
方案三:设置哲学家拿刀叉的时候存在差异,分奇偶来确定拿刀叉的方式
#define N 5 //哲学家个数
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操作是不会阻塞的。