【操作系统】死锁预防与死锁避免(银行家算法)
2026/6/30 14:01:11 网站建设 项目流程

考点频率:★★★★★(死锁预防考概念,银行家算法是计算题常客)
难度:⭐⭐⭐
建议:掌握四种死锁预防方法及其对应的破坏条件;理解银行家算法的数据结构与安全序列判断

1️⃣ 回顾:死锁的必要条件

上一篇文章提到,死锁必须同时满足四个条件:

  1. 互斥:资源一次只能给一个进程使用。
  2. 持有并等待:进程占着已有的资源,同时等待新的资源。
  3. 不可抢占:进程已获得的资源只能自己释放,不能被强行剥夺。
  4. 循环等待:多个进程形成一个首尾相接的资源等待环。

处理死锁有三种策略:预防(破坏条件)、避免(分配前检查安全)、检测与恢复(事后处理)。今天重点讲前两种。

2️⃣ 死锁预防(破坏必要条件)

预防的思想很简单:既然四个条件必须同时满足才能死锁,那就主动破坏其中至少一个条件。

必要条件破坏方法思路缺点
互斥尽量让资源可共享(如只读文件)改造资源属性大多数硬件资源(如打印机)无法共享,难以实现
持有并等待进程一次性申请所有资源要么全给,要么一个不给资源利用率低;可能发生饥饿(某个进程长期申请不到全量资源)
不可抢占允许强行剥夺资源进程申请新资源被拒时,必须释放已有资源实现复杂,适用于状态易保存的资源(如CPU,不适用于打印机这种)
循环等待资源有序分配(给资源编号,必须按编号顺序申请)按统一顺序申请,避免环编号需要合理规划,实际使用中可能不够灵活

软考常考:给定一个场景,问“该措施破坏了死锁的哪个条件?”——找出措施对应的破坏对象即可快速作答。

3️⃣ 死锁避免(银行家算法)

预防是“硬性规定”,比较粗暴。避免则是“动态判断”——每次分配资源前,先模拟分配,看看系统是否会进入不安全状态,如果会,就暂不分配,让进程等待。

3.1 安全状态与不安全状态

  • 安全状态:系统能按某种顺序为所有进程分配所需资源,使它们都能顺利完成。这种顺序称为安全序列
  • 不安全状态:不存在这样的分配顺序。系统进入不安全状态后,有可能发展为死锁。

注意:不安全状态 ≠ 死锁。不安全状态是“可能发生死锁”的危险区,银行家算法的目标就是避免进入不安全状态。

3.2 银行家算法的数据结构

nnn个进程、mmm类资源为例:

数据结构含义示例
Available(长度为mmm当前系统中各类资源的可用数量Available = (2, 1)表示资源A剩2个,资源B剩1个
Maxn×mn \times mn×m矩阵)每个进程对各类资源的最大需求量Max[P1] = (3, 2)表示P1最多需要A资源3个、B资源2个
Allocationn×mn \times mn×m矩阵)每个进程已经获得的各类资源数量Allocation[P1] = (1, 0)表示P1已获得A资源1个
Needn×mn \times mn×m矩阵)每个进程尚需的各类资源数量,Need = Max - AllocationNeed[P1] = (2, 2)表示P1还需要A资源2个、B资源2个

3.3 安全性检查算法(寻找安全序列)

这是银行家算法的核心判断流程,后续请求分配时都要调用它。

  1. 设置两个向量:Work = Available(当前可用资源),Finish = false(所有进程初始标记为未完成)。
  2. 寻找一个进程PiP_iPi,满足:
    • Finish[i] == false
    • Need[i] <= Work(即当前可用资源能满足该进程的剩余需求)
  3. 若找到,则假设该进程运行完毕,释放它所占用的资源:Work = Work + Allocation[i]Finish[i] = true,记录PiP_iPi到安全序列。
  4. 重复步骤2-3。
  5. 若所有进程的Finish都为true,则系统处于安全状态;否则为不安全状态

3.4 银行家算法的请求处理流程

当进程PiP_iPi发出资源请求Request_i(长度为mmm的向量)时,操作系统按以下步骤处理:

  1. 合法性检查:如果Request_i > Need[i],则报错(进程申请的量超过了它宣称的最大值)。
  2. 可用性检查:如果Request_i > Available,则进程需等待(当前资源不够)。
  3. 试分配:先假装把资源分给进程:
    • Available = Available - Request_i
    • Allocation[i] = Allocation[i] + Request_i
    • Need[i] = Need[i] - Request_i
  4. 安全性检查:执行 3.3 节的算法。如果系统处于安全状态,则正式分配;否则撤销试分配,让进程等待。

试分配 + 回滚 是银行家算法的精髓:宁可现在不让它通过,也不冒险进入不安全状态。

4️⃣ 死锁预防 vs 死锁避免

对比项死锁预防死锁避免(银行家算法)
时机系统设计时,静态约束运行时,动态判断
手段破坏四个必要条件之一分配前检查是否安全
资源利用率较低(一次性分配或限制顺序)较高(按需分配)
实现复杂度简单较复杂(需维护矩阵、运行安全性检查)
适用场景小型嵌入式系统、资源可预知的场景资源可动态申请的系统(如银行、数据库)
对进程的要求无特殊要求进程必须预先声明最大需求(Max)

5️⃣ 经典例题

例题1(死锁预防):某系统规定,进程必须一次性申请所有需要的资源,只有全部资源都可用时才分配。该措施破坏了死锁的哪个必要条件?

A. 互斥
B. 持有并等待
C. 不可抢占
D. 循环等待

解析:一次性申请所有资源,要么全给,要么全不给。进程在等待时不会持有任何资源,因此破坏了“持有并等待”条件。选B


例题2(银行家算法-安全序列判断):某系统有 3 个进程 P1、P2、P3,两类资源 A、B,总数分别为(5, 3)。当前分配情况如下:

进程AllocationMax
P1(1, 0)(3, 2)
P2(2, 1)(4, 2)
P3(0, 1)(2, 1)

求当前系统是否存在安全序列。

  1. 计算 Need:

    • Need[P1] = (3,2) - (1,0) = (2,2)
    • Need[P2] = (4,2) - (2,1) = (2,1)
    • Need[P3] = (2,1) - (0,1) = (2,0)
  2. 计算 Available:

    • 已分配总量Allocation_Total = (1+2+0, 0+1+1) = (3, 2)
    • Available = (5,3) - (3,2) = (2,1)
  3. 执行安全性检查:

    • Work = (2,1)。寻找Need[i] <= Work的进程。
    • P1:Need(2,2) <= (2,1)?不满足(第二个数 2 > 1)。
    • P2:Need(2,1) <= (2,1)?满足。将 P2 加入安全序列,Work = (2,1) + Allocation[P2](2,1) = (4,2),标记 P2 完成。
    • 继续找:P1:Need(2,2) <= (4,2)?满足。将 P1 加入,Work = (4,2) + (1,0) = (5,2)
    • P3:Need(2,0) <= (5,2)?满足。将 P3 加入。
    • 所有进程完成。安全序列为:P2 → P1 → P3

答案:存在安全序列P2 → P1 → P3,系统处于安全状态。

6️⃣ 记忆口诀

预防死锁破四因,一次申请或排序。
避免死锁银行家,分配之前先检查。
Available 看余量,Need 等于 Max 减 Allocation。
找到 Need 小于 Work,完成释放 Work 加。

7️⃣ 小测验(评论区对答案)

在上题中,若 P3 此时发出请求Request = (1, 0),银行家算法是否应分配给 P3?

提示:先检查 Request <= Need[P3] 和 Request <= Available,然后试分配,再判断安全性。

🔔本专栏日更2篇,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容

#软考中级 #软件设计师 #死锁预防 #银行家算法 #死锁避免 #操作系统

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询