- 1、本文档共138页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
6.6 哲学家就餐问题 吃饭的布置很简单,如图6-15所示:一张圆桌上有一大碗面和5个盘子,每位哲学家一个,还有5把叉子。每位想吃饭的哲学家将坐到桌子旁分配给他的位置上,使用盘子两侧的叉子,取面和吃面。问题是:设计一套礼仪(算法)以允许哲学家吃饭。算法必须保证互斥(没有两位哲学家同时使用同一把叉子),同时还要避免死锁和饥饿(此时,该术语的字面含义和算法的意思相同)。 图6-15 哲学家的就餐布局 6.6 哲学家就餐问题 这个问题确实说明了死锁和饥饿中的基本问题。此外,解决方案的研究展现了并发程序设计中的许多困难。哲学家就餐问题可以视为当应用程序中包含并发线程的执行时,协调处理共享资源的一个有代表性的问题。因此,该问题是评价同步方法的一个测试标准。 6.6.1 基于信号量解决方案 图6-16给出了基于信号量的解决方案。每位哲学家首先拿起左边的叉子,然后拿起右边的叉子。在哲学家吃完面后,这两把叉子又被放回桌子。这个解决方案会导致死锁:如果所有的哲学家在同一时刻都感到饥饿,他们都坐下来,都拿起左边的叉子,都伸手拿右边的叉子但都没拿到。在这种有损尊严的状态下,所有的哲学家都会处于饥饿状态。 图6-16 哲学家就餐问题的第一种解决方案 6.6.1 基于信号量解决方案 为避免死锁的危险,可以再另买5把叉子(一种更卫生的解决方案),或者教会哲学家仅用一把叉子吃面。另一种方法是,考虑增加一位服务员,他只允许4位哲学家同时进入餐厅,由于最多有4位哲学家就座,因而至少有一位哲学家可以拿到两把叉子。图6-17显示了这种方案,这里再次使用了信号量,这个方案不会发生死锁和饥饿。 图6-17 哲学家就餐问题的第二种解决方案 6.6.2 基于管程解决方案 图6-18给出了基于管程的哲学家就餐问题的解决方案。这种方案定义了一个含有5个条件变量的向量,每把叉子对应一个条件变量。这些条件变量用来标示哲学家等待的叉子可用情况。另外,用一个布尔向量记录每把叉子的可用情况(true表示叉子可用)。管程包含了两个过程。get_forks函数用于表示哲学家取他/她左边和右边的叉子。如果至少有一把叉子不可用,那么哲学家进程就会在条件变量的队列中等待。这可让另外的哲学家进程进入管程。Release_forks函数用来标示两把叉子可用。 图6-18 哲学家就餐问题 的管程解决为案 6.6.2 基于管程解决方案 注意,这种解决方案的结构和图6-16中的信号量解决方案相似。在这两种方案中,哲学家都是先取左边的叉子,然后取右边的叉子。和信号量不同的是,管程不会发生死锁,因为在同一时刻只有一个进程进入管程。比如,第一位哲学家进程进入管程保证了只要他拿起了左边的叉子,在他右边的哲学家可以拿到其左边的叉子之前(即这位哲学家右边的叉子),就一定可以拿到右边的叉子。 Thanks! 6.4.3 破坏不可抢占条件 然而,并不是所有的资源都可以进行类似的虚拟化。例如,数据库中的记录或者操作系统中的表都必须被锁定,因此存在出现死锁的可能。 6.4.4 破坏环路等待条件 现在只剩下一个条件了。消除环路等待有几种方法,一种是保证每一个进程在任何时刻只能占用一个资源,如果要请求另外一个资源,它必须先释放第一个资源。但假若进程正在把一个大文件从磁带机上读入并送到打印机打印,那么这种限制是不可接受的。另一种避免出现环路等待的方法是将所有资源统一编号,如图6-12 a)所示。现在的规则是:进程可以在任何时刻提出资源请求,但是所有请求必须按照资源编号的顺序(升序)提出。进程可以先请求打印机后请求磁带机,但不可以先请求绘图仪后请求打印机。 图6-12 破坏环路等待条件 6.4.4 破坏环路等待条件 现在只剩下一个条件了。消除环路等待有几种方法,一种是保证每一个进程在任何时刻只能占用一个资源,如果要请求另外一个资源,它必须先释放第一个资源。但假若进程正在把一个大文件从磁带机上读入并送到打印机打印,那么这种限制是不可接受的。另一种避免出现环路等待的方法是将所有资源统一编号,如图6-12 a)所示。现在的规则是:进程可以在任何时刻提出资源请求,但是所有请求必须按照资源编号的顺序(升序)提出。进程可以先请求打印机后请求磁带机,但不可以先请求绘图仪后请求打印机。 6.4.4 破坏环路等待条件 若按此规则,资源分配图中肯定不会出现环。让我们看看在有两个进程的情形下为何可行,参看图6-12 b)。只有在A请求资源j且B请求资源i的情况下会产生死锁。假设i和j是不同的资源,它们会有不同的编号。若i j,那么A不允许请求j,因为这个编号小于A已有资源的编号;若i j,那么B不允许请求i,因为这个编号小于B已有资源的编号。不论哪种情况都不可能产生死锁。 6.4.4 破坏环路等待条件 对于多于两个进程
文档评论(0)