哲学家就餐问题

问题描述:

五个哲学家(A~E)围着一张圆桌就餐,他们每个人面前都有一盘通心粉。由于通心粉很滑,所以需要两只筷子才能夹住,但每两个盘子之间只放着一只筷子,如下图。
哲学家只有两个动作:要么就餐,要么思考。而且他们之间从不交谈。
当一个哲学家饿了的时候,就拿起盘子左右两边的筷子开始就餐(不能同时拿起两只筷子)。就餐完以后,就把筷子放回盘子左右,继续思考。
这里写图片描述

由于他们之间互不交谈,所以很容易出现“死锁”:假如每个人都拿着左边的筷子,则所有人都在等右边的筷子,谁都吃不了。
我们可以规定,拿着一只筷子等待另一只筷子的时间超过五分钟就放下手中的筷子,并且再等待五分钟之后进行下一次尝试。
这个策略消除了死锁,不过还是有可能发生“活锁”:假如这五个人同时拿起左边的筷子,大家都在等另一只筷子,五分钟之后大家同时放下筷子。再过五分钟之后又同时拿起左边的筷子……

在计算机领域中,哲学家就餐问题可以抽象成资源抢占问题,筷子就是“资源”。一种常用的计算机技术就是给资源“加锁”,一个资源同时只能供一个程序或者一段代码访问。当一个程序要使用的资源被另外一个程序锁定的时候,只能等待资源被解锁。这就容易出现死锁情况,当有两个程序需要访问两个相同的资源时,如果每个程序都锁了一个资源,那么两者都在等待对方解锁另一个资源的解锁,最后谁都无法执行。

以下介绍三种解决方案。


服务生

就就餐问题,我们可以引入一个服务生,哲学家要经过服务生同意才能拿筷子,因为服务生知道哪只筷子在使用,他可以阻止死锁的发生。
这很好理解,只有当盘子左右的筷子都空闲的时候,服务生才会同意哲学家就餐,这样就不存在有人拿着一只筷子在等待另一只筷子的情况,也就杜绝了死锁的发生。


资源分级

另外一种方法就是给资源分级,例如上图中的五只筷子,给它们分级为1~5五个等级。
约定:每位哲学家在就餐拿筷子的时候,只能先拿级别比较低的筷子,然后才能拿级别比较高的。用餐完以后,先放下级别比较高的筷子,再放下编号比较低的。

这样也不会出现死锁的情况。
假如大家同时拿起一只筷子,那么级别最高的5号筷子一定还留在桌子上。此时哲学家A或者E就能拿起它凑成两只筷子开始进餐。进餐完以后放下筷子,其他哲学家又能进餐了……


Chandy/Misra

这是由K. Mani Chandy和J. Misra提出的又一种解法:

  1. 刚开始的时候,把每只筷子都分给编号比较小的哲学家,即有:A~1,B~2,C~3,D~4,E~5。并把筷子都定义为“脏的”。
  2. 当某位哲学家要使用筷子的时候,他缺哪只筷子,就向拥有那只筷子的哲学家发送一个请求。
  3. 当拥有筷子的哲学家收到请求时,如果筷子是脏的,就把筷子擦干净并交出去;否则就继续留着。
  4. 当哲学家拥有两只干净的筷子时就可以就餐了,吃完以后筷子就变成脏的了。如果有哲学家之前请求过其中一只筷子,则把筷子擦干净并交出去。

示例:

  1. 起初,先把 5 只筷子分别分给 A~E 五位哲学家,并定义为脏的。
  2. 假设B想要吃东西了,他把手里的2号筷子擦干净,可是还缺1号筷子呀,于是就向拥有1号筷子的A发送一个请求。
  3. A收到请求,因为此时1号筷子是脏的,所以A得把1号筷子擦干净,并交给B。
  4. B有两只筷子了,准备开吃了。可就在此时,C也想吃东西了,向B发送过来一个请求,想要2号筷子。
  5. B手里的2号筷子是干净的呀,于是B先吃自己的,吃完以后2号筷子变成脏的了,B再把筷子擦干净并交给C。
    …………
    …………


转载请注明出处,谢谢!(原文链接:http://blog.csdn.net/bone_ace/article/details/46362599
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页