来自操作系统概念
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];
这允许哲学家在她饿的时候推迟自己,但是 无法获得她需要的筷子。
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);
很容易证明这个解决方案确保没有两个邻居 同时进食并且不会发生死锁。
然而,我们注意到,哲学家可能会饿死 死亡即可。我们不提供解决此问题的方法而是 把它作为锻炼给你。
为什么监控解决方案没有死锁?
为什么哲学家可能会饿死?
这个问题的解决方案是什么?
感谢。
答案 0 :(得分:2)
要理解为什么两个邻居永远不能同时进食,请查看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
都不吃饭。
Starvation是可能的,因为signal()不公平:它会随机唤醒任何等待的线程,因此可能不会长时间唤醒某个线程。