6.6.4 破坏环路等待条件

现在只剩下一个条件了。消除环路等待有几种方法。一种是保证每一个进程在任何时刻只能占用一个资源,如果要请求另外一个资源,它必须先释放第一个资源。但假若进程正在把一个大文件从磁带机上读入并送到打印机打印,那么这种限制是不可接受的。

另一种避免出现环路等待的方法是将所有资源统一编号,如图6-13a所示。现在的规则是:进程可以在任何时刻提出资源请求,但是所有请求必须按照资源编号的顺序(升序)提出。进程可以先请求打印机后请求磁带机,但不可以先请求绘图仪后请求打印机。

阅读 ‧ 电子书库
图 6-13 a)对资源排序编号;b)一个资源分配图

若按此规则,资源分配图中肯定不会出现环。让我们看看在有两个进程的情形下为何可行,参看图6-13b。只有在A请求资源j且B请求资源i的情况下会产生死锁。假设i和j是不同的资源,它们会具有不同的编号。若i>j,那么A不允许请求j,因为这个编号小于A已有资源的编号;若i<j,那么B不允许请求i,因为这个编号小于B已有资源的编号。不论哪种情况都不可能产生死锁。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

对于多于两个进程的情况,同样的逻辑依然成立。在任何时候,总有一个已分配的资源是编号最高的。占用该资源的进程不可能请求其他已分配的各种资源。它或者会执行完毕,或者最坏的情形是去请求编号更高的资源,而编号更高的资源肯定是可用的。最终,它会结束并释放所有资源,这时其他占有最高编号资源的进程也可以执行完。简言之,存在一种所有进程都可以执行完毕的情景,所以不会产生死锁。

该算法的一个变种是摈弃必须按升序请求资源的限制,而仅仅要求不允许进程请求比当前所占有资源编号低的资源。所以,若一个进程起初请求9号和10号资源,而随后释放两者,那么它实际上相当于从头开始,所以没有必要阻止它现在请求1号资源。

尽管对资源编号的方法消除了死锁的问题,但几乎找不出一种使每个人都满意的编号次序。当资源包括进程表项、假脱机磁盘空间、加锁的数据库记录及其他抽象资源时,潜在的资源及各种不同用途的数目会变得很大,以至于使编号方法根本无法使用。

死锁预防的各种方法如图6-14所示。

阅读 ‧ 电子书库
图 6-14 死锁预防方法汇总