http://book.51cto.com/art/200907/133248.htm
死锁的4个条件的研究表明如果任一条件不满足,就不会出现死锁。
1. 互斥条件
如果系统中的资源可以由多个进程共享,那么就永远不会发生死锁。然而,这种共享不切实际。例如,磁带机、绘图仪或打印机就不能在多个进程之间共享使用。这其中最好的情形就是对打印机使用假脱机技术,即所有打印请求都由一个单独的程序处理。这样可以消除共享请求。当假脱机程序占用打印机时,其他任何进程都不能发送打印机请求,也不能管理打印机。他们可以做的工作就是将数据提交给假脱机程序,以便以后打印。
不幸的是,并非所有的设备都可以使用相同的技术。而且,死锁涉及的除外部I/O设备之外,还包括各种操作系统表、磁盘区和记录等大量资源。此外,不是所有资源都可以采用假脱机这样简单的应用程序进行处理。因此,很难保证避免该条件。
2. 等待条件
禁止进程在已经占用某些资源时等待更多资源,这样可以预防死锁。
这要求进程一开始就声明它期望使用的全部资源。操作系统会检查这些资源是否全部可用,只有可用的时候,才允许该进程开始执行。这种情况下,显然操作系统在分配完资源之后必须更新自己的空闲及可用资源链表。该解决方案很吸引人,但显而易见的是,它不能达到预期效果而且很浪费。如果进程为了更新某些文件需要用8个小时时间,而最后只使用磁带机一分钟以更新控制记录,在整个过程中磁带机都要分配给那个进程。因此,磁带机会空闲8个小时。这期间没有其他的进程可以使用该磁带机。
可以采用该方法的另一种形式。操作系统必须让请求某些资源的进程先放弃已经占用的资源,然后再尝试请求所有要用的资源。如果尝试成功,被放弃的资源才可以重新分配给该进程,这样该进程才可以继续运行。如果失败,被放弃的资源恢复空闲,而进程则必须一直等到那些资源可用为止。每次检查后,进程都放弃已占用的资源,这样就永远不会出现死锁。
该方案也存在很多问题。当进程放弃现有资源之后,也许会有其他一些进程长时间占用一个或多个资源。很容易想象,该策略会导致长时间的延迟、无限期的推迟以及其他不可预测的问题。同样地,这种技术可用于表、信号量等共享资源,但不适用于打印机和磁带机这类资源。想象一下,某个进程在打印到一半的时候放弃使用打印机,而某个其他进程占用该打印机将产生什么样的后果。
3. 非抢占条件
确保不满足"非抢占"条件很困难。如果允许将资源分配给可以强制夺取该资源的进程,也许可以解决死锁问题,但会出现更糟糕的问题。从一个只处理了部分记录的进程强制性地夺走磁带机--因为其他进程请求使用该资源,由此带来的加载/卸载、定位等问题一定令人无法接受。对打印机而言,情形更糟糕。
4. 循环等待条件
显然,克服前三个条件很难,这样就只留下了最后一个条件。如果阻止了循环等待条件,那么也可以阻止死锁。
一种方法是强制进程每次只能占用一种资源。如果它希望使用另一种资源,就必须先放弃占用的资源,然后再请求其他资源。显然,该方法也存在第(3)点中提到的相同缺点。如果进程P占用R1,并且想要使用R2,它就必须先放弃R1,因此另一个进程P2可以获取资源R1。这时将再次出现在进程P1处理了记录的一半之后,将磁带机分配给P2的问题。因此,该解决方案也不能令人满意。
解决该问题的一个更好的方法就是对所有的资源编号,如图7-10所示。
图7-10 对资源的编号
编号 |
资源名称 |
0 |
磁带机 |
1 |
打印机 |
2 |
绘图仪 |
3 |
读卡机 |
4 |
卡片穿孔机 |
现在可以采用一个简单的规则处理循环等待条件。任何进程都必须在执行期间按照编号递增的顺序请求所需的资源。这里再次假定一开始就能获取所有资源的解决方案并不存在。例如,如果进程P1在执行期间的某个时刻需要使用打印机和绘图仪,它必须先请求打印机,然后是绘图仪,因为1<2。
这样可以预防死锁。下面介绍其中的工作原理。假定两个进程P1和P2都在等待使用磁带机和绘图仪。只有当P1占用磁带机并且想用绘图仪,而P2占用绘图仪并且想用磁带机,并且两个进程请求资源的顺序正好反过来,才会出现死锁。这与假设恰好矛盾。因为0<2,每个进程都要在请求使用绘图仪前先请求使用磁带机,无论该进程是P1还是P2。因此,不可能产生死锁。
该方法对两个进程成立,对多个进程也成立。不过,该方案也存在一些或大或小的问题。
想象一下,系统中有两个磁带机T1和T2以及两个进程P1和P2。如果P1占用T1,并请求使用T2,而P2占用T2并请求使用T1,就会产生死锁。这两个都是磁带机,那么应该采用什么样的编号方案呢?给这两个磁带机相同的编号(例如0),即使有一个当前请求资源的编号必须大于等于前一个请求资源编号的原则,也会产生死锁。
这个小问题可以通过使用某种资源编码方案解决。第1位表示资源类型,第2位表示该资源类型中的资源编号。因此,数字00、01、02等表示不同的磁带机,而10、11表示不同的打印机。进程只请求资源类型(如磁带机)。操作系统在内部将该请求转换成对特定资源如00或01的请求。采用上述解决方案,人们认识到如果发生上面这种情况,就会违反前面提出的假设。例如,P1占用00并且请求使用01,因为00<01所以这是可以接受的请求。同时,P2占用01而且请求使用00,因为00<01,所以不可能发生。
不仅要对外部I/O介质编号,而且还要对包括所有进程表、磁盘区(如假脱机文件)在内的全部资源编号。这是很麻烦的工作。
让所有的进程按照预先确定的顺序请求资源几乎是不可能的,因为实际上进程是按照各种顺序请求资源的。等待时间以及因此造成的浪费会很大,这才是主要的问题。
因此,对预防死锁而言,目前还没有令人满意的通用方法,对此还需要深入研究。
另外一篇文章 http://book.51cto.com/art/200907/133346.htm
时间戳的方法
1. 等待死亡法
2. 受伤等待法