Dining-Philosopher's Monitor 解决方案:`pickup(i)` 是不是需要间接调用`self[i].signal()`?

Posted

技术标签:

【中文标题】Dining-Philosopher\'s Monitor 解决方案:`pickup(i)` 是不是需要间接调用`self[i].signal()`?【英文标题】:Dining-Philosopher's Monitor solution: Does `pickup(i)` need to invoke `self[i].signal()` indirectly?Dining-Philosopher's Monitor 解决方案:`pickup(i)` 是否需要间接调用`self[i].signal()`? 【发布时间】:2018-04-04 05:14:31 【问题描述】:

来自操作系统概念

5.8.2 Dining-Philosophers 使用显示器的解决方案

接下来,我们通过展示无死锁来说明监视器的概念 解决餐饮哲学家的问题。该解决方案强加了 一个哲学家只有在两个条件下才能拿起筷子的限制 其中可用。为了编码这个解决方案,我们需要区分 在我们可以找到哲学家的三种状态中。为了这 为此,我们引入如下数据结构:

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

pickup(i) 调用test(i),当条件满足时后者又调用self[i].signal()pickup(i)是否需要间接调用self[i].signal()

谢谢。

【问题讨论】:

不,这是一个丢失的信号,但它对 putdown(i) 很重要 【参考方案1】:

signal() 的调用在拾取期间无效,因为它向当前线程发出信号,根据定义,当前线程不能处于等待状态。

【讨论】:

以上是关于Dining-Philosopher's Monitor 解决方案:`pickup(i)` 是不是需要间接调用`self[i].signal()`?的主要内容,如果未能解决你的问题,请参考以下文章

20190722-Moni和Boly的故事

nGrinder 简易使用教程

Linux涓婻edis鐨勫畨瑁呭拰閮ㄧ讲

Architecture Components

Curl命令执行Http

Goreplay来做流量回放