dead-lock 什么是死锁?如何避免死锁详解( 二 )


下面我们介绍排除死锁的动态策略--死锁的避免,它不限制进程有关申请资源的命令,而是对进程所发出的每一个申请资源命令加以动态地检查,并根据检查结果决定是否进行资源分配 。
就是说,在资源分配过程中若预测有发生死锁的可能性,则加以避免 。这种方法的关键是确定资源分配的安全性 。
1.安全序列我们首先引入安全序列的定义:所谓系统是安全的,是指系统中的所有进程能够按照某一种次序分配资源,并且依次地运行完毕,这种进程序列{P1,P2,...,Pn}就是安全序列 。如果存在这样一个安全序列,则系统是安全的;如果系统不存在这样一个安全序列,则系统是不安全的 。
安全序列{P1,P2,...,Pn}是这样组成的:若对于每一个进程Pi,它需要的附加资源可以被系统中当前可用资源加上所有进程Pj当前占有资源之和所满足,则{P1,P2,...,Pn}为一个安全序列,这时系统处于安全状态,不会进入死锁状态 。
虽然存在安全序列时一定不会有死锁发生,但是系统进入不安全状态(四个死锁的必要条件同时发生)也未必会产生死锁 。
当然,产生死锁后,系统一定处于不安全状态 。
2.银行家算法这是一个著名的避免死锁的算法,是由Dijstra首先提出来并加以解决的 。

  • 背景知识
一个银行家如何将一定数目的资金安全地借给若干个客户,使这些客户既能借到钱完成要干的事,同时银行家又能收回全部资金而不至于破产,这就是银行家问题 。这个问题同操作系统中资源分配问题十分相似:银行家就像一个操作系统,客户就像运行的进程,银行家的资金就是系统的资源 。
  • 问题的描述
一个银行家拥有一定数量的资金,有若干个客户要贷款 。每个客户须在一开始就声明他所需贷款的总额 。
若该客户贷款总额不超过银行家的资金总数,银行家可以接收客户的要求 。客
户贷款是以每次一个资金单位(如1万RMB等)的方式进行的,客户在借满所需的全部单位款额之前可能会等待,但银行家须保证这种等待是有限的,可完成的 。
例如:有三个客户C1,C2,C3,向银行家借款,该银行家的资金总额为10个资金单位,其中C1客户要借9各资金单位,C2客户要借3个资金单位,C3客户要借8个资金单位,总计20个资金单位 。
某一时刻的状态如图所示 。
dead-lock 什么是死锁?如何避免死锁详解

文章插图
 
银行家算法
对于a图的状态,按照安全序列的要求,我们选的第一个客户应满足该客户所需的贷款小于等于银行家当前所剩余的钱款,可以看出只有C2客户能被满足:C2客户需1个资金单位,小银行家手中的2个资金单位,于是银行家把1个资金单位借给C2客户,使之完成工作并归还所借的3个资金单位的钱,进入b图 。同理,银行家把4个资金单位借给C3客户,使其完成工作,在c图中,只剩一个客户C1,它需7个资金单位,这时银行家有8个资金单位,所以C1也能顺利借到钱并完成工作 。最后(见图d)银行家收回全部10个资金单位,保证不赔本 。那麽客户序列{C1,C2,C3}就是个安全序列,按照这个序列贷款,银行家才是安全的 。否则的话,若在图b状态时,银行家把手中的4个资金单位借给了C1,则出现不安全状态:这时C1,C3均不能完成工作,而银行家手中又没有钱了,系统陷入僵持局面,银行家也不能收回投资 。
综上所述,银行家算法是从当前状态出发,逐个按安全序列检查各客户谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户,...... 。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的 。
从上面分析看出,银行家算法允许死锁必要条件中的互斥条件,占有且申请条件,不可抢占条件的存在,这样,它与预防死锁的几种方法相比较,限制条件少了,资源利用程度提高了 。
这是该算法的优点 。其缺点是:
〈1〉这个算法要求客户数保持固定不变,这在多道程序系统中是难以做到的 。
〈2〉这个算法保证所有客户在有限的时间内得到满足,但实时客户要求快速响应,所以要考虑这个因素 。
〈3〉由于要寻找一个安全序列,实际上增加了系统的开销 。
死锁的检测与恢复一般来说,由于操作系统有并发,共享以及随机性等特点,通过预防和避免的手段达到排除死锁的目的是很困难的 。这需要较大的系统开销,而且不能充分利用资源 。为此,一种简便的方法是系统为进程分配资源时,不采取任何限制性措施,但是提供了检测和解脱死锁的手段:能发现死锁并从死锁状态中恢复出来 。因此,在实际的操作系统中往往采用死锁的检测与恢复方法来排除死锁 。


推荐阅读