进程死锁

进程死锁

死锁概述

死锁处理

死锁预防 & 避免
  • 定义:制定相应的 ==协议或者规则== 阻止死锁的发生
死锁预防
死锁避免
  • 定义:每个进程交付 ==必要信息== 给操作系统,操作系统利用相应的算法 ==动态检查== 资源分配的状态

    必要信息:进程需要申请的资源,想要如何申请资源…

  • 核心:利用死锁算法避免死锁的发生

  • 安全状态:操作系统可以按照 ==特定的顺序== 为进程分配资源并且避免死锁发生,称操作系统处于 ==安全状态==

    600acd2964e4bf2de660adb3e4e69f6f.png

  • 算法:

    • 资源分配图法:仅适用于单实例的资源

      • 核心:引入 ==需求边==:需求边表示进程在将来某个时刻可能会需要的资源

      • 规定:进程在执行前在图中的所有边都是需求边;进程在获取到相应资源后由 ==需求边转为分配边== ;进程结束后 ==分配边再次变为需求边==

      • 检测:如果需求边在转为分配边后会产生环,那么操作系统就不会给当前的进程分配该资源

        检测环是否存在可以使用拓扑排序检测

      213310f2ad02a48c56f77269f427c5b4.png

    • 银行家算法:适用于多实例的资源

      • 数据结构:

        参数名 描述
        Available[n] 该数组每个元素表示每种不同类型资源的 ==可分配== 的资源实例数量
        Max[n][m] 该数组第一个参数表示每个不同的进程;第二个参数表示每个进程正常运行需要的每种类型的 ==全部== 资源实例数
        Allocation[n][m] 该数组第一个参数表示每个不同的进程;第二个参数表示每个进程 ==已经被分配== 的每种类型的资源实例数
        Need[n][m] 该数组第一个参数表示每个不同的进程;第二个参数表示每个进程 ==还需要== 的每种类型的资源实例数

        Need = Max - Allocation;之后提到的 Request 并不是 Need

      • 安全性算法

        1. 定义并初始化变量:

          定义 Work[] & Finish[] 数组;令 Work = Available & Finish[i] = false (i=0,1,2...n)

          问题:为什么不直接使用 Availalbe 变量?

        2. 循环遍历进程集合,判断进程还需要的资源实例数和可分配的资源实例数的关系

          • Finish[i] = true 证明该进程已经执行过并且结束了,开始遍历下一个进程

          • Finish[i] = false

            Need[i]Work[i] 就执行第 3 步

            Need[i]Work[i] 就略过当前进程,开始遍历下一个进程

          • 如果没有下一个进程可以遍历了就执行第 4 步

        3. 进程获取资源并执行,执行结束后释放资源

        `Work[i] = Work[i] + Allocation[i]` 更新当前可以分配的资源实例数
        
        `Finish[i]` = `true`
        
        1. 如果 Finish[] 数组中所有元素都为 true,证明系统处于安全状态;如果存在至少一个 false 元素,证明系统处于不安全状态
      • 资源分配算法

        • 引入:

          安全性算法只能够判断进程依靠当前拥有的资源是否可以正常执行

          如果进程需要更多的资源才能够正常进行,显然就需要申请资源,那么安全性算法显然就是不够用的

        • 过程:引入变量 Request[n]:表示当前进程申请的每种类型的资源实例数量

          1. 判断进程 ==申请== 的资源实例数量和 ==还需要== 的资源实例数量
            • Request[i]Need[i] 就执行第 2 步
            • Request[i]Need[i] 将会提示出错;进程申请的资源实例数量超过了正常执行还需要的资源实例数
          2. 判断进程 ==申请== 的资源实例数量和 ==可分配== 的资源实例数量
            • Request[i]Available[i] 就执行第 3 步
            • Request[i]Available[i] 证明当前可分配资源不足以支撑进程的执行,该进程就需要 ==等待==
          3. 操作系统 ==假设== 分配给进程相应的资源实例数量
            • Available[i] = Available[i] - Request[i]
            • Need[i] = Need[i] - Request[i]
            • Allocation[i] = Allocation[i] + Request[i]
          4. 执行安全性算法判断在进程申请资源后系统是否处于安全状态
            • 如果系统处于安全状态,那么系统就真正将资源分配给进程
            • 如果系统处于非安全状态,那么系统就恢复原来的资源分配状态,并且让该进程处于 ==等待==
        • 细节:

  • 死锁避免 & 死锁预防:

    • 死锁预防:死锁预防是从一开始就不允许进程进行某种操作(比如破坏循环等待就不允许申请编号小的资源)

    • 死锁避免:死锁避免则是在一定程度上允许这些操作,通过设计好的算法在运行过程中协调进程,避免死锁的发生

    • 死锁避免允许四个必要条件一起发生 <-> 死锁预防根本不会允许四个条件一起发生

      解释:因为即使四个必要条件一起发生也不一定会导致死锁的出现,所以死锁避免只要采用相应的算法避免就好

    • 死锁避免限制条件弱,但是难以实现相应的算法 <-> 死锁预防限制条件强,容易实现相应的限制

死锁检测 & 恢复
  • 定义:检测系统是否处于死锁状态并且能够从死锁状态中恢复
死锁检测
死锁恢复
  • 资源抢占

  • 进程终止

    • 核心:终止造成死锁的进程来打破死锁

    • 方式

      • 终止 ==所有== 进程:(几乎类似于重启系统)

        • 缺陷:==代价== 非常大,容易导致被终止的进程之前的 ==任务进程丢失==

          代价:这里的代价应该是对于进程而言的,因为可能会造成很多有效数据的丢失

      • 终止 ==部分== 进程

        • 方式:每次终止一个进程后都需要继续调用死锁检测算法判断当前系统是否仍处于死锁

          解释:需要不断尝试当前系统是否处于死锁状态,如果仍然处于死锁状态,也需要继续死锁检测算法寻找造成死锁的进程

        • 缺陷: ==代价== 非常大

          代价:这里的代价应该是在每次都要执行死锁检测算法确定终止进程所造成的开销

忽略
Author: Fuyusakaiori
Link: http://example.com/2021/09/28/os/process/进程死锁/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.