来自操作系统概念
5.8.2使用监视器的餐饮哲学家解决方案
接下来,我们通过展示无死锁来说明监视器的概念
解决餐饮哲学家的问题。此解决方案将
限制哲学家只有在两个人都拿起筷子的情况下
其中可用。要编写此解决方案的代码,我们需要区分
在我们可以找到一个哲学家的三个州中。为了这
目的,我们介绍以下数据结构:
enum {THINKING, HUNGRY, EATING} state[5];
哲学家我只能在她两个的情况下设置变量
state[i] = EATING
邻居不吃饭:
(state[(i+4) % 5] != EATING)
和(state[(i+1) % 5] != EATING)
。我们还需要声明
condition self[5];
这使哲学家i在饿了的时候就推迟了自己,但是
无法获得她需要的筷子。
monitor DiningPhilosophers
{
enum {THINKING, HUNGRY, EATING} state[5];
condition self[5];
void pickup(int i) {
state[i] = HUNGRY;
test(i);
if (state[i] != EATING)
self[i].wait();
}
void putdown(int i) {
state[i] = THINKING;
test((i + 4) % 5);
test((i + 1) % 5);
}
void test(int i) {
if ((state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING)) {
state[i] = EATING;
self[i].signal();
}
}
initialization code() {
for (int i = 0; i < 5; i++)
state[i] = THINKING;
}
}
图5.18餐饮哲学家问题的监视器解决方案。
每个哲学家在开始吃饭之前,必须调用该操作
pickup()
。此举可能导致哲学家被停职处理。成功完成操作后,
哲学家可能会吃东西。此后,哲学家援引
putdown()
操作。DiningPhilosophers.pickup(i);
...
eat
...
DiningPhilosophers.putdown(i);
很容易证明,该解决方案可确保没有两个邻居
同时吃饭,不会发生僵局。
但是,我们注意到,哲学家可能会饿死
死亡。我们没有提出这个问题的解决方案,而是
把它留给你练习。
为什么显示器解决方案没有死锁?
哲学家为什么可能饿死?
该问题有什么解决方案?
谢谢。
最佳答案
要了解为什么两个邻居永远不能同时吃饭,请查看test(int i)
方法。这是将哲学家的状态设置为EATING
的唯一位置:
if ((state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING)) {
state[i] = EATING;
self[i].signal();
}
前面的if条件确保任何哲学家
i
的邻居(i + 4) % 5
和(i + 1) % 5
都没有吃饭。因为signal()不公平,所以可能会出现饥饿:它会随机唤醒任何等待的线程,因此可能不会在任意长时间内唤醒某个线程。