【问题标题】:Non-blocking solution to the dining philosophers哲学家就餐的非阻塞解决方案
【发布时间】:2015-02-16 19:37:04
【问题描述】:

我被要求用 Python 写一个哲学家就餐问题的简单解决方案。这本身似乎很简单,但由于我被要求编写一个非阻塞解决方案,所以有些困惑。我不确定在这种情况下这是什么意思。

有人能给我任何提示或指出正确的方向吗?

【问题讨论】:

标签: python algorithm blocking dining-philosopher


【解决方案1】:

这里是一个非阻塞算法的定义:http://en.wikipedia.org/wiki/Non-blocking_algorithm

此问题的非阻塞解决方案的伪代码:

# The number of forks.
FORKS_COUNT = ... 

# Indicates if the i-th fork is taken or not.
taken = new bool[FORKS_COUNT] 

# The philosopherId is a position at the table.
def haveDinner(philosopherId):
    leftFork = philosopherId
    rightFork = (philosopherId + 1) % FORKS_COUNT
    if leftFork > rightFork:
        swap(leftFork, rightFork)
    while true:
        # Tries to take the left fork.
        while not compare_and_swap(taken[leftFork], false, true):
            # Do nothing.
        # Tries to take the right fork.
        while not compare_and_swap(taken[rightFork], false, true):
            # Do nothing.
        # Eats.
        ...
        # Returns the forks to the table.
        compare_and_swap(taken[leftFork], true, false)
        compare_and_swap(taken[rigthFork], true, false)

此解决方案使用compare-and-swap 成语。

【讨论】:

  • 不知道为什么 busy wait 不能算作“非阻塞”,但我可能错了。
  • @amit 我不确定,但至少这篇文章:justsoftwaresolutions.co.uk/threading/… 说旋转是非阻塞同步的一个例子。
  • @amit 和线程包中的请求、获取和锁定一样吗?
【解决方案2】:

在问题的上下文中,非阻塞意味着没有死锁。即,哲学家不会在已经持有另一个叉子的同时无限期地暂停等待一个叉子。挂起意味着线程出于调度目的而被禁用,并且在另一个线程专门恢复挂起的线程之前不会执行。解决方案必须避免无限期挂起或死锁(即,2 个或更多线程挂起等待彼此继续)。

该解决方案需要一个可以自动授予两个分叉或拒绝请求的仲裁员。如果哲学家不能原子地分叉,那么哲学家必须在随机的时间内思考生命、宇宙和其他一切。经过思考,哲学家再次请求仲裁员原子地获取两个叉子。在放弃两个叉子之前,进食也会随机延迟一段时间。所有随机延迟都是有限的,有一个共同的上限,比如 10 秒或 10 分钟,等等。

这种设计需要一种比较和交换机制来检查和有条件地更新位掩码,每个分叉一个位。该机制是原子的。要么两个位都更新,要么都不更新。

Java 中的示例解决方案适用于任意数量的哲学家,该解决方案仅使用 volatile 字段且没有 synchronized() 块或挂起锁,可在以下位置获得: sourceforge.net/projects/javamutex/

【讨论】:

    【解决方案3】:

    哲学家就餐问题是这样一个场景,你有 N 个哲学家围坐在一张圆桌旁,每个哲学家之间都有一个叉子。如果哲学家想咬一口,那么他或她必须拿起旁边的两个叉子中的一个,然后再拿起另一个叉子。哲学家取出一个字节后,他或她放下两个叉子。

    如果每个哲学家都拿起他们的左叉子,这个场景就会阻塞。然后没有人能拿起正确的叉子吃饭,他们都饿死了。一种解决方案是让每个哲学家都从拿起左叉子开始,除了那些会从拿起右叉子开始的人。

    【讨论】:

    • 非阻塞并不意味着哲学家会饿死,那是死锁。 “非阻塞”是指没有“停止并等待某事发生”阶段,我看不出这个解决方案如何满足这个要求,但请详细说明。
    • @amit 谢谢!我的解决方案对这个问题是错误的,因为它被阻塞了。
    猜你喜欢
    • 1970-01-01
    • 2012-10-11
    • 2017-04-10
    • 2011-07-09
    • 1970-01-01
    • 2018-06-02
    • 2016-03-04
    • 2019-10-28
    • 1970-01-01
    相关资源
    最近更新 更多