将死锁比喻成火灾,处理死锁的方法同样可以类比处理火灾,从而将处理死锁分为预防、避免、检测与恢复四个方面。
- 死锁预防
预防的目的就是从源头杜绝死锁的发生,确保系统永远都不会进入死锁状态。针对coffman的死锁发生的4个必要条件,从这4个必要条件入手,可以得出预防死锁的具体方法。
1.破坏互斥条件
如果一个资源不会被一个进程独自占有,那么就不会发生资源死锁。破坏这个条件的方法就是允许多个进程同时访问一个资源实例。
2.破坏占有和等待条件
禁止已持有资源的进程再等待其他资源。实现方法可以是规定进程在开始执行前就请求全部需要的资源,如果全部资源都可用,那么就分配所有请求资源给该进程,允许这个进程运行,否则则让进程等待,直到所有的请求的资源全部可用才运行程序。
3.破坏不可抢占条件
申请的资源不能立即使用则释放。
4.破坏环路条件
一种实现方法是保证每一个进程在任何时候只能占用一个资源,如果需要请求另一个资源,则必须释放当前占用的资源。另一种是将所有资源统一编号,进程可以在任何时刻提出资源请求,但是所有资源必须按照资源编号的顺序提出。
- 死锁避免
死锁避免需要利用额外的先验证信息,判断系统会不会出现死锁。系统只允许不会出现死锁的进程请求资源。当一个进程在请求资源的时候,系统判断如果系统将请求的资源分配给了该进程,系统会不会发生死锁。如果会,则拒绝请求,避免系统发生死锁。
这种判断也就是判断系统是否出了安全状态。处于安全状态的系统,一定不会发生死锁;反之,处于不安全状态的死锁,可能会出现死锁。处于不安全状态,并不是一定发生死锁。
死锁避免算法——银行家算法
假设R1,R2,R3是三种资源类型,T1,T2,T3,T4是四个进程。银行家算法工作的前提是已知以上三个矩阵的数据,判断在允许所有程序运行的情况下,系统的安全状态,也就是系统会不会死锁。
以上图中的数据为例,银行家算法究竟是怎样工作的?
当前可用资源可以满足T2进程的当前资源请求,那么系统会允许T2的申请,将资源(0,0,1)分配给进程T2,T2完成后释放所有资源,系统当前可用的资源变为(6,2,4) 。系统当前可用资源变为(6,2,4)之后,进程T1,T3,T4的请求都可满足(顺序满足,不是同时满足)。所有进程的资源请求都能满足,该系统就处于安全状态,系统不会发生死锁。
- 死锁检测与恢复
大多数操作系统都忽略死锁,又应用程序处理死锁。鸵鸟算法就是无视死锁的一种死锁恢复算法。
鸵鸟算法:鸵鸟把头埋进沙子里,假装问题根本就没有发生。对于死锁,不采取任何预防措施,在发生死锁之后,系统自动的做重启和恢复。(第一次听说这个算法,惊了!!!还有这种操作,哈哈)
另一种算法是,对于t时刻,假设存在以下状态:
对于进程T1,T3不需要再请求资源,待这两个进程完成之后,可以释放已经占有的资源,当前可用资源变为(3,1,3),此后,当前可用资源数量,满足剩下任意进程的需求,系统不会死锁。本人觉得,差不多就是银行家算法,但是在死锁检查中,这个工作的定时进行的,也就是说,在某一周期内,系统会进行一次该算法,确定系统是否处于安全状态,不会发生死锁。
进行死锁恢复有3种方法:1.终止进程。在终止进程中,比较需要重要考虑的是进程终止的顺序。是根据进程的优先级顺序,还是进程已运行时间,或者是进程占用资源数量,确定先终止哪一个进程? 2.资源抢占。利用资源抢占,打破死锁环路。 3.回滚恢复。回退到安全状态后,重启进程。