`
gaojingsong
  • 浏览: 1201167 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

哲学家就餐问题

阅读更多


 
 


 
问题描述:
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。即使没有死锁,也有可能发生资源耗尽。例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
 
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
解决方案:
服务生解法
一个简单的解法是引入一个餐厅服务生,哲学家必须经过他的允许才能拿起餐叉。因为服务生知道哪只餐叉正在使用,所以他能够作出判断避免死锁。
为了演示这种解法,假设哲学家依次标号为A至E。如果A和C在吃东西,则有四只餐叉在使用中。B坐在A和C之间,所以两只餐叉都无法使用,而D和E之间有一只空余的餐叉。假设这时D想要吃东西。如果他拿起了第五只餐叉,就有可能发生死锁。相反,如果他征求服务生同意,服务生会让他等待。这样,我们就能保证下次当两把餐叉空余出来时,一定有一位哲学家可以成功的得到一对餐叉,从而避免了死锁。
资源分级解法
另一个简单的解法是为资源(这里是餐叉)分配一个偏序或者分级的关系,并约定所有资源都按照这种顺序获取,按相反顺序释放,而且保证不会有两个无关资源同时被同一项工作所需要。在哲学家就餐问题中,资源(餐叉)按照某种规则编号为1至5,每一个工作单元(哲学家)总是先拿起左右两边编号较低的餐叉,再拿编号较高的。用完餐叉后,他总是先放下编号较高的餐叉,再放下编号较低的。在这种情况下,当四位哲学家同时拿起他们手边编号较低的餐叉时,只有编号最高的餐叉留在桌上,从而第五位哲学家就不能使用任何一只餐叉了。而且,只有一位哲学家能使用最高编号的餐叉,所以他能使用两只餐叉用餐。当他吃完后,他会先放下编号最高的餐叉,再放下编号较低的餐叉,从而让另一位哲学家拿起后边的这只开始吃东西。
尽管资源分级能避免死锁,但这种策略并不总是实用的,特别是当所需资源的列表并不是事先知道的时候。例如,假设一个工作单元拿着资源3和5,并决定需要资源2,则必须先要释放5,之后释放3,才能得到2,之后必须重新按顺序获取3和5。对需要访问大量数据库记录的计算机程序来说,如果需要先释放高编号的记录才能访问新的记录,那么运行效率就不会高,因此这种方法在这里并不实用。
这种方法经常是实际计算机科学问题中最实用的解法,通过为分级锁指定常量,强制获得锁的顺序,就可以解决这个问题。
Chandy/Misra解法
1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解法,允许任意的用户(编号P1, ..., Pn)争用任意数量的资源。与迪科斯彻的解法不同的是,这里编号可以是任意的。
1.对每一对竞争一个资源的哲学家,新拿一个餐叉,给编号较低的哲学家。每只餐叉都是“干净的”或者“脏的”。最初,所有的餐叉都是脏的。
2.当一位哲学家要使用资源(也就是要吃东西)时,他必须从与他竞争的邻居那里得到。对每只他当前没有的餐叉,他都发送一个请求。
3.当拥有餐叉的哲学家收到请求时,如果餐叉是干净的,那么他继续留着,否则就擦干净并交出餐叉。
4.当某个哲学家吃东西后,他的餐叉就变脏了。如果另一个哲学家之前请求过其中的餐叉,那他就擦干净并交出餐叉。
这个解法允许很大的并行性,适用于任意大的问题。
  • 描述: 哲学家情景1
  • 大小: 65.4 KB
  • 描述: 哲学家情景2
  • 大小: 125 KB
  • ThreadDemo.rar (110.6 KB)
  • 描述: 哲学家(加密)
  • 下载次数: 4
0
3
分享到:
评论
1 楼 我的网络世界 2016-06-22  
    密码?

相关推荐

    java哲学家就餐问题

    Java哲学家就餐问题是一个经典的多线程同步问题,源自计算机科学家Dijkstra提出的一个思想实验。在该问题中,五个哲学家围坐在一张圆桌旁,每人面前有一根筷子。他们交替进行思考和吃饭,但必须拿到左右两边的两根...

    c语言实现哲学家就餐问题

    ### c语言实现哲学家就餐问题 #### 实验背景与目的 **哲学家就餐问题**是计算机科学中的一个经典问题,通常用于演示并发控制中的死锁现象。这个问题涉及到五个哲学家和五个放在他们之间的筷子(或者叉子),每个...

    6个哲学家就餐问题原代码

    《6个哲学家就餐问题原代码》 哲学家就餐问题是多线程编程中经典的一个死锁问题,它展示了并发操作中可能出现的资源竞争与死锁现象。在这个问题中,我们有6位哲学家围坐在一张圆桌旁,每位哲学家需要两支筷子才能...

    哲学家进餐问题的C语言实现

    哲学家进餐问题(Dining Philosophers Problem)是计算机科学中的一个经典同步问题,由艾兹格·迪杰斯特拉在1965年提出。它以五个正在进餐的哲学家为背景,每个哲学家都有两个习惯:思考和吃饭。在餐桌上有五根筷子...

    哲学家就餐问题源程序

    哲学家就餐问题是一个经典的多线程同步问题,源自计算机科学中的并发控制理论。该问题由Edsger Dijkstra提出,用以模拟五个哲学家在餐桌上的就餐行为:他们每个人都有两只手,一只用来拿筷子(或刀叉),而餐桌上有...

    操作系统:哲学家进餐问题(p,v操作实现互斥与同步)

    分析哲学家进餐问题,p,v操作实现互斥与同步,分析记录性信号量的不足,并指出给改进方法 方法一:最多允许4人同时进餐; 方法二:分奇偶数进餐,以及AND型信号量解决该问题。 (免费下载,无需积分)

    哲学家进餐问题多线程演示代码.zip

    《哲学家进餐问题与C/C++多线程同步实践》 在计算机科学领域,多线程编程是一项关键技能,特别是在解决并发问题时。这里我们关注的是一个经典的并发问题——哲学家进餐问题(Dining Philosophers Problem)。该问题...

    哲学家进餐问题

    哲学家进餐问题

    哲学家进餐问题的代码

    有三个.cpp文件,代码是我亲手写的,都可以运行,这个代码包含有3种方式避免死锁的方法,一个是允许四个哲学家同时进餐,第二个是一下子就拿两根筷子,否则不拿,第三个就是奇数哲学家先拿左边的筷子,偶数哲学家拿...

    C#哲学家就餐问题

    《C#实现哲学家就餐问题详解》 哲学家就餐问题是计算机科学中经典的多线程并发问题,由Edsger W. Dijkstra在1965年提出,旨在模拟多个哲学家在同一时间吃饭的情景,避免他们因筷子争夺而无法进食。在本案例中,我们...

    信号量同步实验报告(哲学家进餐问题避免死锁的三种方法)

    操作系统初学,关于信号量同步的实验报告,用三种方法避免哲学家进餐问题死锁,a:and信号量,b:控制进餐人数,c设置条件

    哲学家进餐问题,操作系统

    "哲学家进餐问题,操作系统" 哲学家进餐问题是计算机科学中的一种经典问题,它是由美国计算机科学家Edsger Dijkstra在1965年提出的。该问题模拟了五位哲学家围坐在圆桌旁,每人面前有一筷子,哲学家们需要拿起左右...

    JAVA实现哲学家就餐问题

    哲学家就餐问题是多线程编程中的一个经典示例,它由计算机科学家Edsger Dijkstra提出,用于模拟并发环境中可能出现的死锁问题。在该问题中,五个哲学家围坐在一张圆桌旁,每个人面前有一根筷子。当哲学家想要吃饭时...

    µCOS-II 信号量试验——哲学家就餐问题

    µCOS-II 信号量试验——哲学家就餐问题 本实验报告旨在介绍µCOS-II操作系统下的信号量试验,通过经典的哲学家就餐问题实验,了解如何利用信号量来对共享资源进行互斥访问。 一、信号量概述 在µCOS-II操作系统...

    哲学家就餐问题(整理)

    ### 哲学家就餐问题详解 #### 一、问题背景及定义 哲学家就餐问题是并发控制领域中的一个经典问题,最初由艾兹格·迪杰斯特拉(Edsger Dijkstra)提出。该问题通常用来阐述同步算法的概念,并且经常被用于测试各种...

    操作系统 哲学家进餐问题 实现 1 输入饥饿哲学家 2 停止就餐 3 显示个哲学家的状态

    操作系统中的“哲学家进餐问题”是一个经典的同步问题,它由计算机科学家Edsger Dijkstra在1965年提出,用于模拟并发进程的竞争条件。在这个问题中,五位哲学家围坐在一张圆桌旁,每人面前有一根筷子。他们交替地...

Global site tag (gtag.js) - Google Analytics