死锁四条件 + 银行家算法

一句话:死锁就是两个进程互相等着对方手里的资源,谁也不让谁,大家一起卡死。银行家算法是操作系统预判”这样分配会不会导致死锁”的防患于未然的手段。

一、死锁四条件——四个条件必须同时满足才会死锁


mindmap

  root((死锁四条件))

    互斥

      资源一次只能给一个进程

    持有并等待

      拿着手里的,等着别人的

    不可剥夺

      别人拿不走我手里的

    循环等待

      你等我、我等他、他等你

条件一句话类比
① 互斥资源一次只能一个进程用厕所一个坑,不能两个人同时上
② 持有并等待拿着自己的,还想拿别人的你占着碗,还想要筷子
③ 不可剥夺进程不主动释放,别人抢不走你不松手,别人拿不走你的碗
④ 循环等待你等我、我等他、他等你,形成环A 等 B、B 等 C、C 等 A

条件 1:互斥(Mutual Exclusion)

 
资源一次只能给一个进程用。
 
打印机:你在打印的时候,别人不能同时打印——互斥。
 
硬盘读:你读文件,别人也能读——不互斥。
 
只有互斥资源才可能死锁。读共享的文件不会死锁。
 

条件 2:持有并等待(Hold and Wait)

 
进程A 拿着打印机不放手,同时还在等扫描仪。
 
"我手里的不能给你,你手里的我也想要。"
 

条件 3:不可剥夺(No Preemption)

 
进程A 不主动释放打印机,谁也别想从 A 手里抢走。
 
除非 A 自愿 release(),否则打印机会一直归 A。
 

条件 4:循环等待(Circular Wait)

 
进程A 等 进程B 的资源
 
进程B 等 进程C 的资源
 
进程C 等 进程A 的资源
 
形成一个环。
 

graph TD

    A[进程A] -->|等在等| B_Res[进程B的资源]

    B[进程B] -->|等在等| C_Res[进程C的资源]

    C[进程C] -->|等在等| A_Res[进程A的资源]

    A_Res -->|被A拿着| A

    B_Res -->|被B拿着| B

    C_Res -->|被C拿着| C

关键:四个条件缺一不可

 
打破任何一个条件,死锁就解了:
 
  ① 不用互斥资源 → 不现实(打印机就是一次一个人用)
 
  ② 不让持有等待 → 要么全给你,要么一个都不给
 
  ③ 允许剥夺 → 操作系统抢走你的资源
 
  ④ 打破循环 → 所有人都按同一个顺序申请资源
 

二、银行家算法(Banker’s Algorithm)——操作系统版”风险控制”

为什么起这个名字?

 
银行的运作:
 
客户找银行贷款 → 银行检查:
 
  "你总共要借 100 万"
 
  "你现在已经借了 60 万"
 
  "你还要再借 20 万"
 
  "我银行现在有 50 万现金"
 
银行算:
 
  借给你 20 万后 → 我手上还剩 30 万
 
  剩下的人还想借钱的话,我还够不够给?
 
  如果够 → 借给你
 
  如果不够,其他人可能还不了款 → 不借!
 
银行家算法 = 银行家放贷前的风险评估。
 

翻译到操作系统

 
进程 = 客户
 
资源(内存/打印机/磁盘)= 钱
 
进程说"我还要资源" = 贷款申请
 
操作系统 = 银行家
 
操作系统在分配资源前先算:
 
  "给了你之后,剩下的资源够不够让所有进程完成任务?"
 
  "够 → 分给你"
 
  "不够 → 先不给你,你等着"
 

三个关键数据

数据含义类比
Max进程总共需要多少资源客户总共要借多少钱
Allocation进程已经拿到了多少客户已经借了多少钱
Need进程还差多少客户还要借多少钱
 
Need = Max - Allocation
 

还有一个:

数据含义
Available系统当前还有多少空闲资源

算法的核心思想

 
进程P 申请资源 →
 
操作系统假装先分给它 →
 
然后检查:剩下的资源能保证所有进程都完成任务吗?
 
  能 → 真的分给它(安全状态)
 
  不能 → 拒绝这次分配(不安全状态)
 

具体流程(以单种资源为例)

 
系统有 10 个资源(比如内存块)
 
三个进程:
 
        Max(总共要)  Allocation(已拿)  Need(还差)
 
进程P1     9               3               6
 
进程P2     4               2               2
 
进程P3     7               2               5
 
已分配 = 3 + 2 + 2 = 7
 
剩余 Available = 10 - 7 = 3
 

现在进程P2 请求再要 1 个资源。

 
P2 的 Need = 2,它还要 2 个。
 
现在 P2 请求 1 个 → 操作系统先假装分给它:
 
假装后的状态:
 
        Allocation   Need
 
P1        3          6
 
P2        3          1   ← 多拿了一个
 
P3        2          5
 
剩余 Available = 10 - (3+3+2) = 2
 

检查是否安全:

 
① 看哪个进程的 Need ≤ Available(2):
 
   P2 的 Need = 1 ≤ 2 → P2 可以完成!
 
   假设 P2 完成了 → 释放它的 3 个资源
 
   Available = 2 + 3 = 5
 
② 现在 Available = 5:
 
   P1 的 Need = 6 > 5 → 不行
 
   P3 的 Need = 5 ≤ 5 → P3 可以完成!
 
   假设 P3 完成了 → 释放它的 2 个资源
 
   Available = 5 + 2 = 7
 
③ 现在 Available = 7:
 
   P1 的 Need = 6 ≤ 7 → P1 可以完成!
 
   释放 P1 的 3 个资源
 
全部都能完成 → 安全状态 ✅ → P2 的请求被批准
 

如果刚才的例子改成不安全

 
假设系统剩余 = 1,P2 请求 1 个后:
 
        Allocation   Need
 
P1        3          6
 
P2        3          1
 
P3        2          5
 
Available = 1
 
检查:
 
  P1 Need=6 > 1 → 不行
 
  P2 Need=1 ≤ 1 → 可以完成
 
  释放 P2 → Available = 1 + 3 = 4
 
  P1 Need=6 > 4 → 不行
 
  P3 Need=5 > 4 → 不行
 
  P1 和 P3 都完成不了 → 不安全状态 ❌
 
  → 拒绝 P2 的请求!
 

安全序列

上面的例子中,找到的完成顺序就是 安全序列

 
安全序列 = [P2, P3, P1]
 
按这个顺序执行,所有进程都能完成。
 
如果存在至少一个安全序列 → 系统处于安全状态。
 

银行家算法的局限

 
① 需要提前知道每个进程的最大需求(Max)
 
   → 实际中进程经常不知道自己要多少资源
 
② 进程数量通常是固定的
 
   → 实际中进程会动态创建和销毁
 
③ 资源数量不变
 
   → 实际中可以加内存条
 
所以银行家算法在实际操作系统中用得不多,
 
但是常考点——考的是"死锁避免"这个思想。
 

三、一句话讲清

Q:死锁四个必要条件是什么?

互斥、持有并等待、不可剥夺、循环等待。四个必须同时满足才死锁,打破任何一个就能预防死锁。

Q:怎么预防死锁?

最实用的是打破循环等待——所有进程按同一顺序申请资源。比如先申请 A 再申请 B,就不会出现 A 等 B、B 等 A 的环。

Q:银行家算法是什么?

死锁避免算法。分配资源前先计算这次分配是否会导致不安全状态——检查是否存在安全序列。如果存在就分配,不存在就拒绝。就像银行家放贷前评估风险。

Q:安全状态和不安全状态的区别?

安全状态存在至少一个安全序列,所有进程能按顺序完成。不安全状态不存在这样的序列,最终可能死锁。但不安全不一定是死锁——只是有风险。

总结:死锁四个条件缺一不可。预防靠打破条件,避免靠银行家算法预先计算,检测靠找环,恢复靠杀进程或剥夺资源。银行家算法的核心是”安全序列”——能不能给所有进程善终。

速记卡(面试闪卡)

Q1:一句话讲清「死锁四条件 + 银行家算法」到底是什么?

A:死锁就是多个进程互相等着对方手里的资源、谁都不松手,全体卡死;银行家算法是提前算”这样分会不会死锁”的风险控制。

Q2:死锁四条件怎么记 —— 怎么理解?

A:像四人上厕所:①互斥——坑位一次只容一人;②持有并等待——占着碗还想要筷子;③不可剥夺——你不松手别人抢不走;④循环等待——A等B、B等C、C等A 成环。四个同时成立才死锁。

Q3:怎么预防死锁 —— 怎么理解?

A:像定规矩:只要打破四条件之一就解。最实用是打破循环等待——所有人按同一顺序申请资源(先 A 再 B),就不会出现 A 等 B、B 等 A 的死环。也可允许剥夺或一次性全给。

Q4:银行家算法怎么理解 —— 怎么理解?

A:像银行放贷前风控:客户(进程)说还要借多少(Need=Max-Allocation),银行家(操作系统)先假装借出,算剩下的钱够不够让所有人还清(存在安全序列)才真借,否则拒。Banker’s Algorithm 防患于未然。

Q5:安全状态 vs 不安全状态 —— 怎么理解?

A:像末日逃生:安全状态存在至少一个”安全序列”,所有人能按顺序拿到资源干完活、释放出来,全员脱困;不安全状态找不到这样的序列,可能最终死锁——但不安全≠已死锁,只是有风险。

Q6:核心速记主线有哪些?

  • 四条件:互斥、持有并等待、不可剥夺、循环等待(同时成立才死锁)

  • 预防:打破任一即可,最常用按序申请打破循环等待

  • 避免:银行家算法先假装分配,验证安全序列再真分

  • 恢复:检测靠找环,恢复靠杀进程或剥夺资源

口诀

A:死锁四条件,互斥等待环;

占碗想筷子,不抢成死滩。

银行先风控,假装贷一环;

安全序列在,全员能过关。

相关链接