一文彻底搞懂死锁

1. 什么是死锁

死锁通常被定义为:如果一个进程集合中的每个进程都在等待只能由此集合中的其他进程才能引发的事件,而无限期陷入僵持的局面称为死锁。

在许多应用中进程需要以独占的方式访问资源,当操作系统允许多个进程并发执行时可能会出现进程永远被阻塞现象,如两个进程分别等待对方所占的资源,于是两者都不能执行而处于永远等待状态,此现象称为死锁。

比如线程 1 拥有了锁 A 的情况下试图获取锁 B,而线程 2 又在拥有了锁 B 的情况下试图获取锁 A,这样双方就进入相互阻塞等待的情况,如下图所示:

在这里插入图片描述

2. 死锁产生的条件

死锁只有同时满足以下四个条件才会发生:

  • 互斥条件:是指多个线程不能同时使用同一个资源。
  • 持有并等待条件:指当线程 A 已经持有了资源 1,又想申请资源 2,而资源 2 已经被线程 C 持有了,所以线程 A 就会处于等待状态,但是线程 A 在等待资源 2 的同时并不会释放自己已经持有的资源 1。
  • 不可剥夺条件:指当线程已经持有了资源 ,在自己使用完之前不能被其他线程获取,线程 B 如果也想使用此资源,则只能在线程 A 使用完并释放后才能获取。
  • 环路等待条件:指的是在死锁发生的时候,两个线程获取资源的顺序构成了环形链。

3. 死锁产生的原因

死锁产生的原因主要是由于多个进程或线程之间相互竞争有限的资源,同时又不愿意主动释放已经占有的资源,从而导致循环等待的情况发生。具体原因包括:

  • 竞争有限资源:多个进程或线程竞争获取一些互斥的资源,如共享内存、文件、锁等。

  • 资源占用等待:某些进程或线程已经占有了一些资源,同时又需要等待其他进程或线程占有的资源。

  • 不可抢占资源:资源无法被强制性地从一个进程或线程中抢占,只能由持有者主动释放。

  • 循环等待:多个进程或线程之间形成了一个等待循环,每个进程或线程都在等待下一个进程或线程所持有的资源。

这些原因导致了进程或线程之间产生了相互依赖的关系,当这种依赖关系形成循环等待时,就会导致死锁的发生。

4. 死锁解决的方法

主要有一下三种方法:

  • 死锁防止
  • 死锁避免
  • 死锁检测和恢复

4.1 死锁防止

  • 在程序运行之前防止发生死锁。

死锁产生的条件有四个,分别是:互斥条件、占有和等待条件、不剥夺条件、循环等待条件。而死锁防止的策略就是至少破坏这四个条件其中一项。

4.1.1 破坏互斥条件

使资源同时访问而非互斥使用,就没有进程会阻塞在资源上,从而不发生死锁。

  • 只读数据文件、磁盘等软硬件资源均可采用这种办法管理;
  • 但是许多资源是独占性资源,如可写文件、键盘等只能互斥的占有;
  • 所以这种做法在许多场合是不适用的。

4.1.2 破坏占有和等待条件

采用静态分配的方式,静态分配的方式是指进程必须在执行之前就申请需要的全部资源,且直至所要的资源全部得到满足后才开始执行。

  • 实现简单,但是严重的减低了资源利用率。
  • 因为在每个进程占有的资源中,有些资源在运行后期使用,有些资源在例外情况下才被使用,可能会造成进程占有一些几乎用不到的资源,而使其他想使用这些资源的进程等待。

4.1.3 破坏不剥夺条件

剥夺调度能够防止死锁,但是只适用于内存和处理器资源。

方法一:占有资源的进程若要申请新资源,必须主动释放已占有资源,若需要此资源,应该向系统重新申请。

方法二:资源分配管理程序为进程分配新资源时,若有则分配;否则将剥夺此进程已占有的全部资源,并让进程进入等待资源状态,资源充足后再唤醒它重新申请所有所需资源。

4.1.4 破坏循环等待条件

给系统的所有资源编号,规定进程请求所需资源的顺序必须按照资源的编号依次进行。

采用层次分配策略,将系统中所有的资源排列到不同层次中

  • 一个进程得到某层的一个资源后,只能申请较高一层的资源
  • 当进程释放某层的一个资源时,必须先释放所占有的较高层的资源
  • 当进程获得某层的一个资源时,如果想申请同层的另一个资源,必须先释放此层中已占有的资源

4.2 死锁避免

  • 各种死锁防止方法能够防止发生死锁,但必然会降低系统并发性,导致低效的资源利用率。

在程序运行时避免发生死锁。

4.2.1 安全状态

在这里插入图片描述

图 a 的第二列 Has 表示已拥有的资源数,第三列 Max 表示总共需要的资源数,Free 表示还有可以使用的资源数。从图 a 开始出发,先让 B 拥有所需的所有资源(图 b),运行结束后释放 B,此时 Free 变为 5(图 c);接着以同样的方式运行 C 和 A,使得所有进程都能成功运行,因此可以称图 a 所示的状态时安全的。

定义:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。

安全状态的检测与死锁的检测类似,因为安全状态必须要求不能发生死锁。下面的银行家算法与死锁检测算法非常类似,可以结合着做参考对比。

4.2.2单个资源的银行家算法

一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。

在这里插入图片描述

上图 c 为不安全状态,因此算法会拒绝之前的请求,从而避免进入图 c 中的状态。

4.2.3 多个资源的银行家算法

在这里插入图片描述

上图中有五个进程,四个资源。左边的图表示已经分配的资源,右边的图表示还需要分配的资源。最右边的 E、P 以及 A 分别表示:总资源、已分配资源以及可用资源,注意这三个为向量,而不是具体数值,例如 A=(1020),表示 4 个资源分别还剩下 1/0/2/0。

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

  • 查找右边的矩阵是否存在一行小于等于向量 A。如果不存在这样的行,那么系统将会发生死锁,状态是不安全的。
  • 假若找到这样一行,将该进程标记为终止,并将其已分配资源加到 A 中。
    -重复以上两步,直到所有进程都标记为终止,则状态时安全的。

如果一个状态不是安全的,需要拒绝进入这个状态。

4.3 死锁检测和恢复

  • 对资源的分配加以适当限制可防止或避免死锁发生,但不利于进程对系统资源的充分共享。

不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复。

  • 如果进程 - 资源分配图中无环路,此时系统没有发生死锁。
  • 如果进程 - 资源分配图中有环路,则可分为以下两种情况:
    • 每种资源类中仅有一个资源,则系统发生了死锁。此时,环路是系统发生死锁的充分必要条件,环路中的进程就是死锁进程。
    • 每种资源类中有多个资源,则环路的存在只是产生死锁的必要不充分条件,系统未必会发生死锁。

4.3.1 每种资源类中仅有一个资源的死锁检测

在这里插入图片描述

上图为资源分配图,其中方框表示资源,圆圈表示进程。资源指向进程表示该资源已经分配给该进程,进程指向资源表示进程请求获取该资源。

图 a 可以抽取出环,如图 b,它满足了环路等待条件,因此会发生死锁。

比如:进程D需要的资源是U、T;进程G需要的资源是V、U;进程E需要的资源是T、V
此时进程D占有资源U,进程E占有资源T,进程G占有资源V
所以此时导致进程D、E、G所申请的资源不能得到全部满足,陷入死锁。

死锁检测算法:

每种类型一个资源的死锁检测算法是通过检测有向图是否存在环来实现,从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁的发生。

4.3.2 每种资源类中有多个资源的死锁检测

在这里插入图片描述

  • 每个资源类用一个方框表示,方框中的原点表示此资源类中的各个资源;

  • 每个进程用一个圆圈来表示,用有向边表示进程申请资源和资源分配情况。

  • 约定方框→圆圈表示资源分配,圆圈→方框表示申请资源。

  • 这种情况下,图3-6 发生了死锁,而图3-7没有发生死锁。

死锁检测算法:

在这里插入图片描述

上图中,有三个进程四个资源,每个数据代表的含义如下:

  • E 向量:资源总量
  • A 向量:资源剩余量
  • C 矩阵:每个进程所拥有的资源数量,每一行都代表一个进程拥有资源的数量
  • R 矩阵:每个进程请求的资源数量

进程 P1 和 P2 所请求的资源都得不到满足,只有进程 P3 可以,让 P3 执行,之后释放 P3 拥有的资源,此时 A = (2 2 2 0)。P2 可以执行,执行后释放 P2 拥有的资源,A = (4 2 2 1) 。P1 也可以执行。所有进程都可以顺利执行,没有死锁。

算法总结:每个进程最开始时都不被标记,执行过程有可能被标记。当算法结束时,任何没有被标记的进程都是死锁进程。

  1. 寻找一个没有标记的进程 Pi,它所请求的资源小于等于 A。
  2. 如果找到了这样一个进程,那么将 C 矩阵的第 i 行向量加到 A 中,标记该进程,并转回 1。
  3. 如果没有这样一个进程,算法终止。

4.3.3 死锁恢复

  • 资源剥夺法
    剥夺陷于死锁的进程所占用的资源,但并不撤销此进程,直至死锁解除。
  • 进程回退法
    根据系统保存的检查点让所有的进程回退,直到足以解除死锁,这种措施要求系统建立保存检查点、回退及重启机制。
  • 进程撤销法
    撤销陷入死锁的所有进程,解除死锁,继续运行。
    逐个撤销陷入死锁的进程,回收其资源并重新分配,直至死锁解除。
    可选择符合下面条件之一的先撤销:
    1.CPU消耗时间最少者
    2.产生的输出量最小者
    3.预计剩余执行时间最长者
    4.分得的资源数量最少者后优先级最低者
  • 系统重启法
    结束所有进程的执行并重新启动操作系统。这种方法很简单,但先前的工作全部作废,损失很大。
  • 30
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值