哲学家就餐问题
典型的互斥制约关系的进程同步问题。描述是:
有五个哲学家在同一张圆桌上用餐与思考。圆桌上为每人配发了一只碗,但仅在他们的每个空隙中配发了一只筷子,也即只有五只筷子可用。要求他们交替进行用餐与思考。平时大家都在思考,当某个哲学家饥饿时会试图去取其左右两边离他最近的筷子。只有在拿到两只筷子时才能进餐,否则只能继续思考。进餐完毕,放下筷子开始思考。
分析:假设吃饭时先拿左手边的,再拿右手边的,那么有可能5个人同时拿起筷子,此时就造成了思索问题,那么我们保证最多4个人同时吃饭:
semaphore chopsticks[5] = {1,1,1,1,1};
semaphore num = 4;
void philosopherDining(){
int i = 0;
while(true){
//思考。。。。。
wait(num);//保证最多4人同时吃饭
wait(chopsticks[i]);//拿起右边的筷子
wait(chopsticks[(i+1) % 5]);//拿起左边的筷子
//就餐。。。。。
signal(chopsticks[(i+1) % 5]);//放下左边的筷子
signal(chopsticks[i]);//放下右边的筷子
signal(num);
}
}
上述实现还有一个问题,就是5个人在同一刻都想吃饭的话,只有一个可以吃,但是最多是两个人可以吃的。我们可以让相邻的人先竞争一个筷子,如果没有抢到,就不要再竞争另一边了,即:奇数先拿左边,偶数先拿右边
semaphore chopsticks[5] = {1,1,1,1,1};
void philosopherDining(){
int i = 0;
while(true){
//思考。。。
if(i % 2 == 0){
wait(chopsticks[i]);//拿起右边的筷子
wait(chopsticks[(i+1) % 5]);//拿起左边的筷子
}else{
wait(chopsticks[(i+1) % 5]);//拿起左边的筷子
wait(chopsticks[i]);//拿起右边的筷子
}
//就餐。。。。。
signal(chopsticks[(i+1) % 5]);//放下左边的筷子
signal(chopsticks[i]);//放下右边的筷子
}
}
用AND型信号量解决:同时竞争两个筷子
int chopsticks[5] = {1,1,1,1,1};
void philosopherDining(){
int i = 0;
while(true){
//思考。。。
Swait(chopsticks[i],chopsticks[(i+1) % 5 );
//就餐。。。。。
Ssignal(chopsticks[i],chopsticks[(i+1) % 5 );
}
}