Concurrency 为什么解决问题的monitor解决方案没有死锁,只有饥饿?

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]!=吃) 我们还需要申

从操作系统概念

5.8.2使用监视器的解决方案

接下来,我们通过介绍无死锁的监视器来说明监视器的概念 解决问题的方法。这一解决方案规定了 限制哲学家只能在两种情况下拿起筷子 其中一个是可用的。要编写此解决方案,我们需要区分 在三个州中,我们可以找到一位哲学家。为此 目的:我们介绍以下数据结构:

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();
}