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

时间:2017-10-23 15:25:35

标签: concurrency operating-system computer-science monitor dining-philosopher

来自操作系统概念

  

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

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

感谢。

1 个答案:

答案 0 :(得分:1)

signal()的调用在拾取过程中没有任何影响,因为它向当前线程发出信号,根据定义它不能处于等待状态。