OS

OS 7死锁

Posted by lsq on December 14, 2018

在多到程序环境下,多个进程可能竞争一定数量的资源。如果某个进程申请的资源不可用,那么该进程进入等待状态。如果所申请的资源被其他等待进程占有,那么该等待进程有可能再也无法改变其状态,称为死锁(deadlock)。在正常操作模式下,进程只能按如下顺序使用资源:申请->使用->释放。多个线程可能因为竞争共享资源而容易出现死锁。如果在一个系统中下面4个条件同时满足,那么会引起死锁:

  • 互斥:至少有一个资源必须处于非共享模式。
  • 占有并等待:一个进程必须占有至少一个资源,并等待另一资源,而该资源为其他进程所占有。
  • 非抢占:资源不能被抢占。
  • 循环等待:该条件意味着占有并等待条件。

从原理上来说,有三种方法可以处理死锁问题:

  • 可使用协议以预防避免死锁,确保系统不会进入死锁状态。
  • 可允许系统进入死锁状态,然后检测它并恢复.
  • 忽视死锁问题,认为死锁不可能在系统内发生。

死锁预防是一组方法,确保至少一个必要条件不成立,这些方法通过限制如何申请资源的方法来预防死锁。死锁避免要求操作系统事先得到有关进程申请资源和使用资源的额外信息。如果系统不使用死锁预防或死锁避免算法,那么可提供一个算法来检查系统状态以确定死锁是否发生,并提供另一个算法来从死锁中恢复。对许多系统,死多很少发生,与使用频繁且开销昂贵的死锁预防、死锁避免和死锁检测与恢复算法相比,可使用人工重启的方式。

1 死锁预防

出现死锁有四个必要条件,只要确保至少一个必要条件不成立,就能预防死锁发生,下面讨论通过限制四个必要条件来预防死锁。

  • 互斥:对于非共享资源,必须要有互斥条件,所以通常不能通过否定互斥条件来预防死锁。
  • 占有并等待:为了确保占有并等待条件不会在系统内出现,必须保证当一个进程申请一个资源时,它不能占有其他资源。一种协议是每个进程在执行前申请并获得所有资源;第二种协议是允许进程在没有资源时才可申请资源,也可以理解为边执行边申请。这两种协议共同的缺点时,必须在开始前申请所有资源,这可能导致饥饿。
  • 非抢占:对于非抢占条件,为了确保这一条件不成立,可以使用如下协议:如果一个进程占有资源并申请另一个不能立即分配的资源,那么其现已分配的资源都可被抢占。换句话说,这些资源都被隐式地抢占了。这个协议通常应用于状态可以保存和恢复的资源,如CPU寄存器和内存。
  • 循环等待:一个确保此条件不成立的方法是,给所有的资源进行完全排序,要求必须按照递增顺序进行申请资源,排序的规则应该根据系统内资源使用的正常顺序来定义,否则依然不能避免死锁。

2 死锁避免

通过限制资源申请的方式来预防死锁的副作用是会降低设备的使用率和系统吞吐率,避免死锁的另一个方法是,获得以后如何申请资源的附加信息。有了关于每个进程的申请与释放的完全顺序,可决定进程是否因申请而等待。每次申请要求系统考虑现有可用资源,现已分配给每个进程的资源和每个进程将来申请与释放的资源,以绝当当前进程的申请是否满足或必须等待,从而避免死锁的发生。

如果系统按照某个顺序为每个进程分配资源(不超过其最大值)并能避免死锁,那么系统的状态就是安全的。或者说,如果存在一个安全序列,那么系统处于安全状态。安全序列的定义如下:如果对于进程顺序<p1, p2, …, pn>,每个进程pi仍然可以申请的资源数小于当前可用资源,加上所有进程pj(j<i)所占有的资源,那么该进程顺序就是安全序列。如果没有这样的序列存在,那么系统状态就处于不安全状态,但是不安全状态并不一定导致死锁。

有了安全状态的概念,可定义避免算法以确保系统不会死锁,其思想是简单地确保系统始终处于安全状态。当进程申请一个可用的资源时,系统必须确定这一资源申请是可以立即分配还是要等待,只有分配后系统仍处于安全状态才允许申请。与没有采用死锁避免算法相比,这种情况下的资源使用率可能更低。

下面介绍银行家算法,名字来源以该算法可用于银行系统,当不能满足所有客户的要求时,银行绝不会分配其现金。算法思想是:当新进程进入系统时,它必须说明其可能需要的每种类型资源实例的最大数量,这一数量不能超过系统资源总和。当用户申请一组资源时,系统必须确定这些资源的分配是否仍会是系统处于安全状态。如果是就可分配资源;否则进程必须等待直到某个其他进程释放足够资源为止。

3 死锁检测和恢复

死锁检测算法根据每种资源类型只有单个实例和多个实例两种情况进行不同处理。如果所有资源都只有单个实例,那么可以采用等待图的方法。等待图是从资源分配图中删除所有资源类型节点,再合并适当边得到的,当且仅当等待图中有一个环时,系统中存在死锁。如果每种资源都多个实例,可以使用类似银行家算法来进行死锁检测。

如果检测到系统中存在死锁,那么就需要打破死锁。一种方法是终止一个或多个进程;另一种方法是从一个或多进程中抢占资源。进程终止分为两种:终止所有死锁进程和一次终止一个进程直到死锁被打破,这两种方法的开销都很大。如果通过抢占资源来打破死锁,需要逐步从进程中抢占资源给其他进程使用,直到死锁环被打破。这时有三个问题需要处理:1)选择哪个进程牺牲;2)对牺牲进程做什么安排;3)如何确保不总是牺牲同一个进程。

Reference

操作系统概念
操作系统-清华大学
Operation system: three easy piece