死锁产生的条件及其如何处理

2023-10-31

一、原因与条件

产生死锁的原因主要是:

  1. 因为系统资源不足。
  2. 进程运行推进的顺序不合适。
  3. 资源分配不当等。

发生死锁的四个必要条件:

  1. 相互排斥:所涉及的资源必须不可共享;否则,将不会阻止进程在必要时使用资源。
  2. 保留并等待或部分分配:进程在等待其他(请求的)资源时必须保留已分配的资源。如果该进程必须在请求一个或多个新资源时释放其资源,则不会发生死锁,因为该进程不会阻止其他人使用它控制的资源。
  3. 无抢占:在使用该资源时,不得剥夺进程资源。否则,死锁将不会发生,因为操作系统可以简单地从运行的进程中获取足够的资源以使任何进程都能完成。
  4. 资源等待或循环等待不存在:一个循环的流程链,每个流程都拥有资源,该资源当前由链中的下一个流程所请求。如果是这样,则循环定理(指出“资源图中的循环对于发生死锁是必要的”)表明可能发生死锁

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

 

二、处理死锁的基本方法

死锁预防:通过设置某些限制条件,去破坏死锁的四个条件中的一个或几个条件,来预防发生死锁。但由于所施加的限制条件往往太严格,因而导致系统资源利用率和系统吞吐量降低。

死锁避免:允许前三个必要条件,但通过明智的选择,确保永远不会到达死锁点,因此死锁避免比死锁预防允许更多的并发。

死锁检测:不须实现采取任何限制性措施,而是允许系统在运行过程发生死锁,但可通过系统设置的检测机构及时检测出死锁的发生,并精确地确定于死锁相关的进程和资源,然后采取适当的措施,从系统中将已发生的死锁清除掉。

死锁解除:与死锁检测相配套的一种措施。当检测到系统中已发生死锁,需将进程从死锁状态中解脱出来。常用方法:撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程。死锁检测盒解除有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

2.1 死锁预防

在程序运行之前预防发生死锁:防死锁算法可确保至少一种必要条件(互斥,保留和等待,无抢占和循环等待)不成立。但是,大多数预防算法的资源利用率很低,因此导致吞吐量降低。

  • 破坏互斥条件:它是设备的固有属性所决定的,不仅不能改变,还应该加以保证。由于无法安全地共享某些资源,因此无法                            始终通过防止相互排斥(使所有资源可共享)来防止死锁。
  • 破坏占有和等待条件:我们将看到两种方法,但都有其缺点。
  1. 资源可以在开始执行之前获取所有必需的资源。这样可以避免死锁,但是由于进程占用了资源,即使不需要时也会减少吞吐量。在这段时间内,它们可能已被其他进程使用。
  2. 第二种方法是仅在资源不占用任何其他资源时才请求该资源。这可能会导致饥饿,因为所有必需资源可能无法始终免费提供。
  • 破坏不可抢占条件:我们将在此处看到两种方法。这里的挑战是,只有当我们可以保存当前状态并且可以从已保存状态稍后重新启动进程时,才能抢占资源。
  1. 如果处理请求由另一个等待资源持有的资源,则可以将该资源从另一个等待资源中抢占。
  2. 在第二种方法中,如果某个流程请求的资源不容易获得,那么它将抢占该资源所拥有的所有其他资源。  
  • 破坏环路等待:为了避免循环等待,可以对资源进行排序,并且我们可以确保每个进程只能按这些数字的递增顺序请求资源。该算法本身可能会增加复杂性,也可能导致不良的资源利用。

2.2 死锁避免

两种死锁避免算法:

  • 进程启动拒绝:如果一个进程的请求会导致死锁,则不启动该进程。
  • 资源分配拒绝:如果一个进程增加的资源请求会导致死锁,则不允许此分配(银行家算法)。

如您所见,大多数预防算法的资源利用率很低,因此导致吞吐量降低。相反,我们可以尝试通过使用有关进程对资源使用的先验知识来避免死锁,这些知识包括可用资源,分配的资源,将来的请求以及将来的进程发布。

大多数避免死锁算法都需要每个进程预先告知可能需要的每种类型的最大资源数量。根据所有这些信息,我们可以决定进程是否应该等待资源,从而避免循环等待的机会。

避免死锁算法会尽量避免为进程分配资源,否则会导致系统处于不安全状态。 由于在某些情况下不会立即进行资源分配,因此避免死锁算法还存在资源利用率低的问题。

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

通常我们可以使用资源分配图来避免死锁。如果资源分配图中没有周期,则没有死锁。如果存在周期,则可能出现死锁。如果每种资源只有一个实例,则一个循环意味着出现死锁。资源分配图的顶点是资源和过程。资源分配图具有请求边缘和分配边缘。从进程到资源的边缘是请求边缘,从资源到进程的边缘是分配边缘。平滑的边缘表示将来可能会提出请求,并以虚线表示。基于平滑的边缘,我们可以查看是否有周期的机会,然后批准请求,以使系统再次处于安全状态。

考虑具有平滑边缘的图像,如下所示:

如果将R2分配给p2,并且如果P1请求R2,则将出现死锁。P1占据着R1等待着R2,P2占据着R2等待着R1。

如果一个资源有多个实例,则资源分配图不是很有用。在这种情况下,我们可以使用Banker算法。在此算法中,每个进程必须预先告知所需的每种类型的最大资源,并以每种类型的最大可用实例为准。只有在分配确保安全状态的情况下,才进行资源分配。否则流程需要等待。

Banker的算法可以分为两部分:•安全算法(如果系统是否处于安全状态)。资源请求算法假设分配,并查看系统是否处于安全状态。如果新状态不安全,则不会分配资源,并且数据结构将还原到其先前状态;在这种情况下,进程必须等待资源。

2.2.1. 单个资源的银行家算法

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

 

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

2.2.2. 多个资源的银行家算法

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

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

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

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

2.2.3 安全性算法

安全性算法是由银行家算法改进的其更通用。

安全性算法具体步骤描述,其中 i是进程,j是资源
(1) 设置两个向量: 在执行安全算法开始时,Work∶=Available; Finish[i]:= False;
(2) 从进程集合中找到一个能满足下述条件的进程: ① Finish[i]= False; ② Need[i,j]≤Work[j];
      若找到, 执行步骤(3), 否则,执行步骤(4)。
(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
      Work[j]∶= Work[j]+ Allocation[i, j];
      Finish[i]∶= true; go to step 2;
(4) 如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。

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

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

2.3 死锁检测与解除

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

2.3.1 鸵鸟策略

把头埋在沙子里,假装根本没发生问题。

因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。

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

大多数操作系统,包括 Unix,Linux 和 Windows,处理死锁问题的办法仅仅是忽略它。

2.3.2 每种类型一个资源的死锁检测

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

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

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

2.3.3 每种类型多个资源的死锁检测

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

  • 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. 如果没有这样一个进程,算法终止。

2.3.4 死锁恢复

  • 利用抢占恢复
  • 利用回滚恢复
  • 通过杀死进程恢复

2.4 三种策略的对比

 

参考文献:CSDN-邪三一Github-CyC2018

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

死锁产生的条件及其如何处理 的相关文章

  • Android Dialog用法

    摘要 创建对话框 一个对话框一般是一个出现在当前Activity之上的一个小窗口 处于下面的Activity失去焦点 对话框接受所有的用户交互 对话框一般用于提示信息和与当前应用程序直接相关的小功能 Android API 支持下列类型 创

随机推荐

  • 什么是结构因果模型

    结构因果模型 结构因果模型简介 定义 历史 因果关系之梯 关联 干预 反事实 因果 因果和相关 类型 必要因 充分因 促成因 模型 因果图 模型元素 连接方式 链 叉 对撞 节点类型 中介变量 混杂因子 工具变量 孟德尔随机化 关联 独立性
  • linux内核编程入门之proc文件读写

    my proc dir proc create myproc 0666 NULL proc ops 在 proc 根目录下创建文件myproc 文件的权限为0666 文件的读写操作定位在proc ops中 具体可以看下面源码 可以使用 ec
  • 蜂群算法论文【matlab代码与仿真】

    一 算法流程 蜂群算法 Bee Algorithm 是一种启发式优化算法 灵感来源于蜜蜂在寻找食物和选择巢穴的行为 这种算法模拟了蜜蜂群体中的集体智能 用于解决各种优化问题 蜂群算法的基本思想是通过模拟蜜蜂的搜索行为来寻找最优解 算法中的蜜
  • 仙境传说RO:添加自定义道具

    仙境传说RO 添加自定义道具 大家好 我是艾西今天和大家聊一下仙境传说RO怎么添加自定义道具 在我们开服时加入一些道具模组等往往会让我们的服务器更有特色以及消费点 那么让我们直接进入正题开始操作 此处我们讲的过程中以红色药水举例 喜欢的可以
  • php弹窗一次,网站广告弹出层(每天弹出一次)

    网站广告弹出层 每天弹出一次 可以有两种做法 一 是标识符存入数据库 二 利用Jquery cookie 我这里做的是比较简单的用到的知识是Jquery cookie 这里要注意的一点是jquery cookie的值 火狐能够获取 IE 3
  • VMware桥接模式无法识别英特尔AX200无线网卡解决办法

    1 先到英特尔网站下载最新驱动 更新网卡驱动适用于 Intel 无线网络卡的 Windows 10 和 Windows 11 Wi Fi 驱动程序 2 到控制面板查看无线网卡属性是否有下图组件 没有的话 依次操作 安装 服务 添加 从磁盘安
  • Unidbg系列--Ollvm字符串解密

    Ollvm字符串解密 原理 使用unidbg框架 模拟调用So文件 并Hook内存写操作 当so解密操作写入内存时 回调获取解密字符串 并将其写入新so文件中 达到反OLLVM字符串加密的目的 解密脚本 package com xCrack
  • openmvs编译

    OpenMVG 和OpenMVS在Widows下使用Vs2019编译 black world 博客园 cnblogs com cmake src G Visual Studio 16 2019 A x64 DCMAKE TOOLCHAIN
  • pyspark-ml学习笔记:模型评估

    问题是这样的 如果我们想基于pyspark开发一个分布式机器训练平台 那么肯定需要对模型进行评估 而pyspark本身自带模型评估的api很少 想进行扩展的话有几种方案 1 使用udf自行编写代码进行扩展 2 使用现有的 像sklearn中
  • CentOS安装Docker

    Docker是一个开源的容器引擎 它有助于更快地交付应用 Docker可将应用程序和基础设施层隔离 并且能将基础设施当作程序一样进行管理 使用 Docker可更快地打包 测试以及部署应用程序 并可以缩短从编写到部署运行代码的周期 CentO
  • 相机标定实战之双目标定

    相机标定原理 文章目录 相机标定原理 前言 一 采集图像 二 基于Matlab单双目标定流程 采集棋盘图 三 基于OpenCV Python双目标定流程 检测棋盘格角点 对角点进行亚像素精细化 单目标定 双目标定 双目校正 保存标定参数 读
  • 服务器系统怎么设置第一启动项,服务器怎么设置启动项

    服务器怎么设置启动项 内容精选 换一换 华为云帮助中心 为用户提供产品简介 价格说明 购买指南 用户指南 API参考 最佳实践 常见问题 视频帮助等技术文档 帮助您快速上手使用华为云服务 您需要在源端服务器上安装迁移Agent并且输入目的端
  • java: 非法字符: ‘\ufeff‘解决方法

    出现问题 在使用idea时候会出现java 非法字符 ufeff 这样的情况 原因 出现这样的问题来源于这个BOM 一般在编写时候会给你默认添加这样的一个BOM头 是隐藏起来的 编译时候会给出现编码混乱问题 详见了解BOM 隐藏字符 百度百
  • 三调与二调图斑叠加分析,筛选不同地类面积占比,筛选举证图斑

    主要步骤 标识数据 叠加分析 用标识 生成所有相交图斑 属性有原图斑的地类和国家的地类 以及原图斑的面积 生成的面域 增加4个字段 图斑的三调一级类 图斑的国家NYYPDL 是否相同 标识后的图斑面积 转换三调地类为二调的一级类 转换国家地
  • 《最强大脑第九季》C#手撸傅立叶残影题目

    在最新一季的最强大脑总决赛中 有一个比赛项目 傅立叶残影 感觉印象深刻 原理就是五根针首尾相连 按照自身的转速和杆长运动 根据提供的每根杆的转速和杆长来判断出尾部运动的残影轨迹 原理比较简单 就是一个连杆运行 好吧 知道原理就可以动手开始撸
  • 整数除法JS

    param number a param number b return number var divide function a b const MIN Math pow 2 31 const MAX Math pow 2 31 1 判断
  • Redis的事务学习及用Redis实现乐观锁,redis数据类型总结

    一 Redis的事务操作 1 Redis 事务可以一次执行多个命令 并且带有以下三个重要的保证 批量操作在发送 EXEC 命令前被放入队列缓存 收到 EXEC 命令后进入事务执行 事务中任意命令执行失败 其余的命令 依然被执行 但是如果队列
  • C语言基础知识--变量

    目录 一 C语言变量 1 局部变量 1 什么是局部变量 2 代码示例 3 代码讲解 2 全局变量 1 什么是全局变量 2 代码示例 3 代码讲解 3 静态变量 1 全局静态变量 2 局部静态变量 3 代码示例 4 代码讲解 4 const常
  • 用Python制作一个自动抢票脚本

    前言 大麦网 是中国综合类现场娱乐票务营销平台 业务覆盖演唱会 话剧 音乐剧 体育赛事等领域 但是因为票数有限 还有黄牛们不能丢了饭碗 所以导致了 很多人都抢不到票 那么 今天带大家用Python来制作一个自动抢票的脚本小程序 知识点 面向
  • 死锁产生的条件及其如何处理

    一 原因与条件 产生死锁的原因主要是 因为系统资源不足 进程运行推进的顺序不合适 资源分配不当等 发生死锁的四个必要条件 相互排斥 所涉及的资源必须不可共享 否则 将不会阻止进程在必要时使用资源 保留并等待或部分分配 进程在等待其他 请求的