Concurrency 为什么解决问题的monitor解决方案没有死锁,只有饥饿?
从操作系统概念 5.8.2使用监视器的解决方案 接下来,我们通过介绍无死锁的监视器来说明监视器的概念 解决问题的方法。这一解决方案规定了 限制哲学家只能在两种情况下拿起筷子 其中一个是可用的。要编写此解决方案,我们需要区分 在三个州中,我们可以找到一位哲学家。为此 目的:我们介绍以下数据结构:Concurrency 为什么解决问题的monitor解决方案没有死锁,只有饥饿?,concurrency,operating-system,synchronization,monitor,livelock,Concurrency,Operating System,Synchronization,Monitor,Livelock,从操作系统概念 5.8.2使用监视器的解决方案 接下来,我们通过介绍无死锁的监视器来说明监视器的概念 解决问题的方法。这一解决方案规定了 限制哲学家只能在两种情况下拿起筷子 其中一个是可用的。要编写此解决方案,我们需要区分 在三个州中,我们可以找到一位哲学家。为此 目的:我们介绍以下数据结构: enum {THINKING, HUNGRY, EATING} state[5]; 哲学家只有当她有两个 邻居没有吃饭:(州[(i+4)%5]!=吃饭)和 (声明[(i+1)%5]!=吃) 我们还需要申
enum {THINKING, HUNGRY, EATING} state[5];
哲学家只有当她有两个
邻居没有吃饭:(州[(i+4)%5]!=吃饭)
和
(声明[(i+1)%5]!=吃)
我们还需要申报
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;
}
}
很容易证明,此解决方案确保没有两个邻居
同时进食,并且不会发生死锁
然而,我们注意到,一个哲学家有可能饿死
死亡。我们不提供此问题的解决方案,而是
把它作为练习留给你
为什么监视器解决方案没有死锁
为什么哲学家可能饿死
这个问题的解决方案是什么
谢谢。要理解为什么两个邻居不能同时吃饭,请看一下
测试(inti)
方法。这是唯一一个哲学家的状态设置为吃的地方:
if ((state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING)) {
state[i] = EATING;
self[i].signal();
}
前面的if条件确保,对于任何哲学家来说,其邻居(i+4)%5
和(i+1)%5
都没有进食
饥饿是可能的,因为这是不公平的:它随机唤醒任何等待的线程,因此可能在任意长时间内不会唤醒某个线程。死锁是不正确同步的结果。在给定的代码中如何表示同步?使用的编程语言是什么?谢谢。Java的
signal()
的链接并没有说它随机选择了一个等待的线程。还是我错过了什么?这本书介绍了不限于Java的一般概念,signal
是否通常实现为选择一个随机等待线程?等待的线程可以放在FIFO队列中吗?本书还提供了信号量方面的monitor实现()。这本书还提到信号量上的等待线程可以用FIFO实现,所以我认为FIFO对于monitor是一样的,对吗?signal
的Javadoc说“如果有线程在这种情况下等待,那么就选择一个线程来唤醒。”它没有说明这一点,所以你不能假设任何事情。此外,类注释说“条件因素排除了对象监视器方法(wait、notify和notifyAll)”,而notify
的Javadoc明确声明“如果有线程正在等待此对象,则选择其中一个进行唤醒。选择是任意的,由实现自行决定。”谢谢。有没有理由不使用FIFO?有没有可能做到公平?
if ((state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING)) {
state[i] = EATING;
self[i].signal();
}