【问题标题】:Dining philosophers : Chandy-Misra approach : how does it avoid a deadlock?餐饮哲学家:Chandy-Misra 方法:如何避免僵局?
【发布时间】:2013-10-11 10:19:24
【问题描述】:

我正在尝试,但是有一个问题: 在 wiki 中,该算法的第三点说:

当一个有叉子的哲学家收到请求消息时,如果叉子是干净的,他会保留叉子,但如果叉子脏了就放弃。如果他把叉子送过来,他会在这样做之前清理叉子

我试图理解为什么这不会导致死锁?如果一位哲学家有一个干净的叉子,并等待从邻近的餐厅/哲学家那里得到另一个干净的叉子,而后者也在等待叉子,这可能会累积成僵局,对吗?一位哲学家总是在等待另一位哲学家的分叉?

ps:我是线程和并发的新手,把它当作一个学习项目。

编辑:提供分叉的实际位置,发布此内容以询问分叉是否应该是可变的。 pLeft , pRight 是左右哲学家,fLeft 和 fRight 是左右叉子。

private Fork giveFork(Philosopher diner) {
        Fork forkToGive;

        if (this.pLeft.equals(diner)) {
            // give left fork to left philosopher
            if (this.fLeft.isClean)
                forkToGive = null; // don't give
            else {
                forkToGive = new Fork(this.fLeft.id, true); // give the fork
            }

        } else if (diner.pRight.equals(this)) {
            // give right fork to right philosopher
            if (this.fRight.isClean)
                forkToGive = null;
            else {
                forkToGive = new Fork(this.fRight.id, true);
            }
        } else {
            // default value , i'm not yet sure if this code
            // can be theoretically reached
            forkToGive = null;
        }

        return forkToGive;

    }

我还没有弄清楚在哪里同步它,但我觉得仍然需要同步。就像当两个用餐者时,说第一个和第三个向第二个哲学家要叉子。

【问题讨论】:

  • 描述说如果叉子脏了,哲学家就放弃叉子,一开始所有叉子都是脏的。
  • 是的,但我不明白如何初始化“所有”叉子?我有收藏叉子吗?并随着时间的推移将它们更改为清洁/肮脏?我试图尽可能多地保持不变性,所以我决定不保留一组可变分叉,并在需要时创建并提供新的干净分叉。
  • forks 共享资源并且必须是可变的(否则,不需要整个协议,因为每个哲学家都可以得到干净的 fork 对)。通常,所有花哨的同步协议都需要管理跨进程/线程共享的可变数据,如果您的数据是不可变的(纯粹是功能性的),则无需担心同步。
  • 从给脏叉子的哲学家的观点来看,他必须先清理它,现在假设我创建了脏叉子的副本,只让它干净,然后替换脏叉子有了新的干净的,仍然有一个叉子,并且还有不变性..
  • 假设giveFork() 由提供fork 的哲学家执行,您需要同步才能将生成的fork 返回给请求者(例如,通过wait()/notifyAll())。但是由于创建了分叉,这段代码比必要的更复杂。其实不需要专门的Fork类,你只需要数组ForkState forks[philosophersNr],并让你的各方在上面同步。

标签: algorithm concurrency dining-philosopher


【解决方案1】:

你引用的来源解释了它:

但是,如果系统初始化为完全对称状态, 就像所有拿着左侧叉子的哲学家一样,那么图表是 循环一开始,他们的解决方案无法防止死锁。 初始化系统,使 ID 较低的哲学家有脏 forks 确保图最初是非循环的。

因此,您需要将系统初始化为非对称状态, 并且该组规则旨在不离开所需的(非死锁状态)。

【讨论】:

  • 嘿,谢谢你提到那部分。我错过了 。但我真的不明白如何保持我的叉子:可变与否。你能帮忙吗?
  • 两者都应该像在任何一个点上一样工作,一个分叉只有一个所有者:原始算法是为分布式环境设计的,因此它有助于从消息传递的角度进行思考(所以每次你通过一个分叉,您创建并发送一条新消息)
猜你喜欢
  • 2017-04-10
  • 2016-03-04
  • 2022-12-29
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 2010-10-26
相关资源
最近更新 更多