一、哲学家进餐问题
1、利用记录型信号量解决哲学家就餐问题会导致死锁
若五位哲学家同时饥饿而各自拿起了左边的筷子,这使五个信号量 chopstick 均为 0,当他们试图去拿起右边的筷子时,都将因无筷子而无限期地等待下去,即可能会引起死锁。
// 哲学家线程函数,参数I是哲学家的编号
void philosopher(int I)
{
// 无限循环,模拟哲学家的一生
while (true)
{
// 哲学家正在思考
思考;
// 尝试拿起左边的筷子,如果筷子不可用,则等待
wait (chopstick [ I ]);
// 尝试拿起右边的筷子,如果筷子不可用,则等待
// 这里使用了取模运算,确保哲学家数组的索引不会越界
wait (chopstick [(I+1)%5]);
// 拿起两只筷子后,开始进餐
进餐;
// 进餐完毕,释放左边的筷子
signal (chopstick [I]);
// 释放右边的筷子
signal (chopstick [(I+1)%5]);
}
}
在以上描述中,当哲学家饥饿时,总是先去拿他左边的筷子,即执行 ait(cho ti ck[i]);成功后,再去拿他右边的筷子,即执行 ait(cho ti ck[(i+ l)%5]); 又成功后便可进餐。进餐毕,又先放下他左边的筷子,然后再放他右边的筷子。虽然,上述解法可保证不会有两个相邻的哲学家同时进餐,但却有可能引起死锁。假如五位哲学家同时饥饿而各自拿起左边的筷子时,就会使五个信号量 cho ti ck 均为 0: 当他们再试图去拿右边的筷子时,都将因无筷子可拿而无限期地等待。
2、解决办法
(1)规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反。按此规定,将是1,2号