代码改变世界

《现代操作系统》笔记——死锁

2016-07-14 18:32  shuaihanhungry  阅读(1217)  评论(0编辑  收藏  举报

死锁可以发生在进程之间,可以发生在同一进程不同线程之间,还可以发生在不同机器之间。
软硬件资源均可引起死锁,软件资源如文件、数据库等,硬件资源如打印机、磁盘等。
死锁方面的大多数研究工作在1980年以前就完成了。

大部分死锁都和资源有关,资源分为可抢占的和不可抢占的,存储器就是一类可抢占的资源,有关可抢占资源的潜在死锁通常可能通过在进程之间重新分配资源而化解,总是来说,死锁和不可抢占资源有关。

假设前提:如果某个进程请求资源失败,那么它就进入休眠状态。

根据系统的不同,资源请求失败时进程可能会自动被阻塞,也可能会返回一个错误代码。

最常见的死锁类型是资源死锁(还有通信死锁),资源死锁跟进程的数量以及占有或者请求的资源数量和种类都是无关的。

Coffman等人(1971)总结了发生(资源)死锁的四个必要条件:
1、互斥条件。
2、占有和等待条件。
3、不可抢占条件。
4、环路等待条件。
死锁发生时,必是4个条件同时满足。如果其中有任何一个条件不满足,死锁就不会发生。

Holt(1972)指出如何用有向图建立上述四个条件的模型。在有有向图中有两类节点:用圆形表示的进程,用方形表示的资源。从资源节点到进程节点的有向边表示资源已被请求、授权并被进程占用,从进程节点到资源节点的有向边表示当前进程正在请求该资源,并且该进程已被阻塞,处于等待该资源的状态。按照请求和释放的次序一步步进行,每一步之后都检查图中是否包含了环路。如果有环路,那么就有死锁,反之,则没有死锁。

四种处理死锁的策略:
1、忽略该问题。鸵鸟算法。
2、检测死锁并恢复。(假设当一个进程请求资源时,它一次就请求所有的资源)

  • 每种类型一个资源的死锁,可以通过构造一张资源分配图,进行深度优先搜索,检测图中是否有存在环。
  • 每种类型多个资源的死锁,可以通过矩阵算法来检测。先构建现有资源向量E、可用资源向量A、当前分配矩阵C、请求矩阵R(E、A、C之间存在某种关系),再开始会对进行做标记,进程被标记后就表明它们能够被执行,不会进入死锁,当算法结束时,任何没有标记的进程都是死锁进程。
  • 关于检测时机有几种方法,每当有资源请求时去检测,每隔固定时间检测一次,当CPU的使用率到某一域值时去检测。
  • 关于死锁恢复有几种方法,利用抢占恢复,利用回滚恢复,通过杀死进程恢复(杀死环中进行或环外进程)。

3、仔细对资源进行分配,动态地避免死锁。

  • 安全状态:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。换句话说,通过仔细的调度就能够避免死锁的状态就是安全状态。
  • 系统必须能够判断分配资源是否安全,并且只能保证安全的条件下分配资源。
  • 通过资源轨迹图可以直观感受死锁避免。
  • 在任何时刻,当前状态包括了E、A、C、R,通过它们可以判断一个状态是安全状态还是不安全状态。
  • 不安全状态并不是死锁,从安全状态出发,系统能够保证所有进程都能完成,而从不安全状态出发,就没有这样的保证。
  • Dijkstra(1965)提出了一种能够避免死锁的调度算法,称为银行家算法,该算法是死锁检测算法的扩展。银行家算法就是对每一个请求进行检查,如果这一请求会到达安全状态,那么就满足该请求,若否,那么就推迟对这一请求的满足。不安全状态并不一定引起死锁,由于客户(进程)不一定需要其最大贷款额度,但银行家(操作系统)不敢抱这种侥幸心理。可以把银行家算法进行推广以处理多个资源。
  • 银行家算法虽然很有意义但缺乏实用价值,因为很少有进程能够在运行前就知道其所需资源的最大值。

4、通过破坏引起死锁的四个必要条件之一,防止死锁的产生。

  • 死锁避免从本质上说是不可能的,因为它需要获未来的请求,而这些请求是不可知的。
  • 如果能够保证四个条件中至少有一个不成立,那么死锁将不会产生(Havender,1968)。
  • 破坏互斥条件,使用假脱机技术(并转串);破坏占有和等待条件,在开始就请求全部资源;破坏条件不可抢占条件,资源虚拟化;破坏环路等待条件,将资源编号,按编号顺序请求资源。