The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.1 野蛮人进餐问题

第五章 稍欠经典的同步问题

 

5.1 野蛮人进餐问题

 

这个问题来自安德鲁斯的并发编程[1]。

一个野蛮人部落从一个大锅里吃公共晚餐,大锅可以容纳大量的炖传教士。【这个问题是基于对狩猎 - 采集社会中西方传教士历史的卡通化表现。 一些幽默的意图是针对哲学家进餐的问题,但这里的“野蛮人”的表现并不是为了比以前的哲学家的表现更为现实。 如果你对狩猎 - 采集社会感兴趣,我推荐Jared Diamond的《Guns, Germs and Steel》,Napoleon Chagnon的《The Yanomamo》,以及Redmond O'Hanlon的《In Trouble Again》,但不推荐Tierney的《Darkness in El Dorado》,我认为这是不可信的。】当一个野蛮人想吃东西时,他会帮助自己从锅中解脱,除非它是空的。 如果锅是空的,野蛮人将厨师吵醒,然后等到厨师重新装满锅。

任意数量的野蛮人线程都运行以下代码:

一个厨师线程运行此代码:

同步约束是:

  • 如果锅底为空,野蛮人无法调用getServingFromPot。
  • 只有在锅为空时,厨师才能调用putServingsInPot。

思考:为野蛮人和厨师添加满足同步约束的代码。

 

5.1.1 野蛮人进餐问题提示

很容易使用信号量来跟踪食物的数量,就像生产者 - 消费者问题一样。 但是为了在锅为空时向厨师发出信号,线程必须在递减信号量之前知道它是否必须等待,而我们就是不能这样做。

另一种方法是使用记分板来跟踪食物的数量。 如果一个野蛮人发现计数器为零,他会唤醒厨师并等待锅已满的信号。 以下是我使用的变量:

毫不奇怪,emptyPot表示锅是空的,而fullPot表示锅已满。

 

5.1.2 野蛮人进餐问题方案

我的解决方案是记分牌模式与集合点的组合。 这是厨师的代码:

野蛮人的代码只是稍微复杂一点。 当每个野蛮人通过互斥体时,他会检查锅。 如果它是空的,他会向厨师发出信号并等待。 否则,他递减servings并从锅中获得了一份食物。

是野蛮人而不是厨师,将servings设定为M,这似乎很奇怪。这并不是必需的; 当厨师运行putServingsInPot时,我们知道持有互斥锁的野人正在等待fullPot。 所以厨师可以安全地进入餐厅。 但在这种情况下,我决定让野蛮人去做,以便通过查看代码可以清楚地看到所有对servings的访问都在互斥锁内。

此解决方案无死锁。 唯一出现死锁的可能性发生在持有互斥锁的野蛮人等待fullPot时。 在他等待的时候,其他野蛮人在互斥锁上排队等候。 但最终厨师将运行并发出fullPot信号,这可以让等待的野蛮人恢复并释放互斥锁。

这个解决方案是否假设这个锅是线程安全的,或者确保putServingsInPot和getServingFromPot是互斥执行的?

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值