死锁的产生和解决方法

当两个或两个以上的进程占有自身资源,并请求对方资源时,会导致每个进程都无法向前推进,造成死锁。

死锁产生的必要条件

  1. 互斥条件: 资源分配是排他性的,每个资源只能同时给一个进程使用
  2. 不可剥夺条件: 进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,只能进程自己主动释放
  3. 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
  4. 循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求。

解决死锁的方法

鸵鸟策略

当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略,也就是忽略它。

死锁预防

死锁的预防是破坏死锁产生的四个必要条件之一,属于静态策略。

  1. 互斥条件,是资源本身特点,不可避免

  2. 破坏不可剥夺条件: 采用 可剥夺资源,允许进程强行从占有者那里夺取某些资源。缺点是可能降低系统性能。、

  3. 破坏请求和保持条件: 采用 资源一次性分配 ,所有进程在开始执行前请求所需要的全部资源。比如数据库中的一次封锁法。 缺点是进程执行是动态的,不可预测;资源利用率低;降低进程的并发性

  4. 破坏循环等待条件: 采用 资源有序分配,系统给进程编号,按某一顺序申请资源,释放资源则反序释放。 比如数据库中的顺序封锁法。 缺点是增加了系统的开销

  • 一次封锁法:要求每个事务在开始执行时必须把需要访问的数据项全部加锁。
  • 顺序封锁法:对数据库中的事务访问的所有数据项规定一个加锁顺序,每个事务在执行过程中必须按此顺序对所需的数据项加锁。

死锁避免(动态策略)

在进程在每次申请资源时,对其操作进行动态检查,根据检查结果决定是否分配资源,若在资源分配过程中预测有发生死锁的可能,则进行死锁的避免。关键是确定资源分配的安全性。

1. 安全状态

系统中的所有进程按照某一调度次序分配资源,并且进程能够依次运行完毕,那这种进程序列 {P1,P2,…,Pn} 是一个安全序列,此时系统处于安全状态,这种情况不会发生死锁。如果发生死锁,那么系统一定处于不安全状态。

在安全序列中,系统当前可用资源 + 前一个进程 P[i] 所释放的资源能够 >= P[i+1] 还需要的资源

系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配后系统处于安全状态,则将资源分配给进程;否则,令进程等待。

2. 银行家算法

银行家算法是一种避免死锁的算法,实质是设法保证系统动态分配资源后不进入不安全状态,以避免可能产生的死锁。

单个资源的银行家算法

问题描述:
一个银行家拥有一定数量的资金,有若干个客户要贷款。每个客户须在一开始就声明他所需贷款的总额。若该客户贷款总额不超过银行家的资金总数,银行家可以接收客户的要求。客户在借满所需的全部单位款额之前可能会等待,但银行家须保证这种等待是有限的,可完成的。

银行家算法是从当前状态出发,逐个按安全序列检查各客户谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户,也就是说是算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。

缺点:

  1. 要求客户数保持固定不变,这在多道程序系统中难以做到
  2. 要保证所有客户在有限的时间内得到满足,但实时客户要求快速响应,可能难以快速响应
  3. 寻找一个安全序列会增加系统的开销
多个资源的银行家算法

n 个进程 m 个资源。

检查一个状态是否安全的算法如下:

  1. 查找需求矩阵中是否存在一行小于等于剩余可用资源。如果不存在这样的行,那么系统将会发生死锁,状态是不安全的。
  2. 假若找到这样一行,将该进程标记为终止,并将其已分配资源加到可用资源中。
  3. 重复以上两步,直到所有进程都标记为终止,则状态时安全的。如果一个状态不是安全的,需要拒绝进入这个状态。

死锁的检测与恢复

由于操作系统有并发、共享及随机性等特点,通过死锁预防和死锁避免需要较大的系统开销,且不能充分利用资源,因此这样难以达到排除死锁的目的。

死锁的检测:建立资源分配表和进程等待表。

死锁的恢复:从其他进程强制剥夺资源给死锁进程;可以直接撤销死锁进程,或撤销代价最小的进程;回退策略。

参考资料

什么是死锁及死锁的必要条件和解决方法
【操作系统】处理死锁的方法