浅谈死锁

  说起死锁,首先我们就要知道死锁是怎么形成的。比如:两个工作进程在工作中都被阻塞,双方都希望对方能释放自己所需要的资源,但是因为无法获得相应的资源继续运行,从而也无法释放自己占有的资源,一直处于这样的僵持状态而形成死锁。

  通过上面的例子,我们可以推断,死锁的形成是因为多个进程竞争资源而无法满足时,陷入无限等待状态而形成死锁。那么我们首先就来了解一下计算机中的资源分类。

1 资源问题

  在系统中有许多类型不同的资源,其中可以引起死锁的主要是,需要采取互斥访问方法的不可以被抢占的资源(临界资源),如打印机、数据文件、队列、信号量等。简单来分可以分为以下两个大类。

  • 可重用性资源和不同重用性资源

  可重用性资源:可以供用户多次使用的资源。资源在使用时只能分配给一个进程使用,数量相当对固定,在运行期间不能创建也不能删除。

  不可重用性资源:运行期间由进程动态地创建和消耗的资源,数量不固定,可能为0,也可能数量很多。一次可以申请若干个可消耗性资源,使用完成不再返回资源类。

  • 可抢占性资源和不可抢占性资源

  可抢占性资源:该资源在分配各某个进程后,可以被其他进程或系统抢占。如优先级高的进程可以抢占优先级低的进程的处理机。

  不可抢占性资源:该资源在分配给某个进程后,只能被该进程用完后自行释放。

  既然了解了操作系统中的资源分类,下面我们就来简单了解一下引起死锁的原因。

2 计算机系统中的死锁

  死锁的起因,通常是源于多个进程对资源的争夺,不仅对不可抢占资源进行争夺时引起死锁,对可消耗资源进行争夺时也会引起死锁。

  • 竞争不可抢占性资源引起死锁。P1进程在持有F1资源时,对F2资源请求;P2进程在持有F2资源时,对F1资源请求,且F1、F2不可被剥夺,就会陷入无限等待引起死锁。
  • 竞争可消耗资源引起死锁

  例如:存在P1、P2、P3三个进程,P1、P2、P3形成环状,P1向P3发出m3信息后消耗P2发来的m1信息,P3向P2发送m2信息后消耗P1发来的m3信息,P2向P1发送m1信息后消耗P3发来的m2信息。

  但是如果改变发送消息与消耗消息的顺序,即先消耗消息再发送消息,就会造成线程等待一条根本不会发出的信息陷入死锁状态。

  • 进程推进顺序不合法,可能会造成死锁。如果到达了不安全的状态,就可能产生死锁。

3 死锁的定义、必要条件

  死锁:如果一组进程的每一个进程都在等待仅由该组进程中的其他进程才能引发的时间,那么该组进程是死锁的

  产生死锁的必要条件,产生死锁就必须同时具备下面四个必要条件,只要其中任何一个条件不成立,死锁就不会发生:

  • 互斥条件。进程所分配到的资源进行排他性使用,在一段时间内,某个资源只能被一个进程占用,其他请求该资源的进程,只能等待。
  • 请求和保持条件。某进程至少保持一个资源,提出对新资源的请求,但新资源被其他线程所占有,则当前线程陷入阻塞,且自己保持的资源不释放。
  • 不可抢占条件。进程保持的资源不能被其他进程抢占。
  • 循环等待条件。发生死锁时,存在一个进程——资源的循环链。即P0等待P1所占用的资源,P1等待P2所占用的资源,P2等待P3所占用的资源,...,Pn等待P0所占用的资源。

4 处理死锁的方法

  • 预防死锁:破坏产生死锁的四个必要条件中的一个或几个
  • 避免死锁:在资源动态分配过程中,用某种方法防止系统进入不安全状态,从而可以避免发生死锁。
  • 检测死锁:通过检测机构及时地检测出死锁的发生,采取适当的措施。
  • 解除死锁:常用的方法,撤销一些线程,回收它们的资源,将他们分配给已处于阻塞状态的进程,使其能继续运行。

5 具体处理方法

  • 预防死锁

  破坏“请求和保持”条件:第一种协议就是在进程开始运行之前,必须一次性地申请其在整个运行过程中所需要的全部资源,从而破坏“请求条件”。第二种协议就是允许一个进程只获得初期所需的资源后,开始运行。在运行期间逐步释放已经用完的资源,再申请新的所需资源。第一种协议简单、易行且安全,但资源被严重浪费,还会经常发生饥饿现象;第二种协议提高了设备的利用率,并且减少了进程发生饥饿的概率。

  破坏“不可抢占”条件:当一个线程保持了某些不可被抢占资源的进程,提出新的资源请求而不能得到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。

  破坏“循环等待”条件:一个能保证“循环等待”条件不成立的方法是,对系统所有资源类型进行线性排序并赋予不同的序号。规定每个进程必须按序号递增的顺序请求资源。即必须先申请序号低的资源,再申请序号高的资源。若保持序号高的资源,想要申请序号低的资源,则需要向释放序号高的资源。

  • 避免死锁,利用银行家算法避免死锁

  利用银行家算法来计算每一个状态是否是系统安全状态,若从安全状态向不安全状态发生了转换,则不分配该进程所申请的资源。具体的安全状态与不安全状态,这里不再赘述,需要了解的童鞋可以去问问度娘。

  • 死锁的检测,该方法用于检测系统状态,以确定系统是否发送了死锁。
  • 死锁的解除。当认定系统中发生了死锁,利用该算法可将系统从死锁状态中解脱出来。

  常采用解除死锁的两种方法是:第一种,抢占资源。从一个或多个线程中抢占足够数量的资源,分配给死锁进程,解除死锁状态。第二种,终止(或撤销)进程。终止(或撤销)系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态中解脱出来。


  本文只是将死锁涉及的概念、原因及解决方法简单列举,供大家复习参考,具体内容,大家可以参考操作系统课本或其他资料中的详细说明,进一步学习。

猜你喜欢

转载自blog.csdn.net/m0_37135421/article/details/80653074