Skip to content

参考:死锁条件、处理策略与银行家算法速查

基于通用操作系统概念 · 核于 2026-08

速查

  • 死锁定义:一组进程互相等待对方资源,永久阻塞、谁也前进不了。
  • 四必要条件:互斥、占有并等待、不剥夺、循环等待——全满足才死锁,破坏其一即预防。
  • 资源分配图(RAG):进程→资源(请求)、资源→进程(分配)。单实例资源有环⇔死锁;多实例需图化简。
  • 四种处理策略:预防(破坏条件)、避免(银行家算法)、检测恢复(允许发生再处理)、鸵鸟(忽略)。
  • 安全状态:存在安全序列(能依次完成的进程序列);安全一定不死锁,不安全只是有风险。
  • 银行家算法:分配前先试探,再跑安全性算法判断是否仍安全,安全才真分配。
  • 鸵鸟策略:Linux/Windows 实际做法——忽略死锁,由应用开发者自行避免。
  • 饥饿:长期得不到资源但能调度;活锁:进程在动但无进展;都不等于死锁。

一、死锁四必要条件

条件含义破坏方法(预防)
互斥(Mutual Exclusion)资源排他,同时只能一个进程用改用共享资源(只读文件/无锁结构),多数资源难破坏
占有并等待(Hold and Wait)持有资源的同时申请新资源一次性申请全部所需资源
不剥夺(No Preemption)资源不可强抢,只能主动释放申请不到就释放已占资源;允许抢占
循环等待(Circular Wait)存在 {P0→P1→...→P0} 等待环资源有序分配(按编号升序申请)

记忆:四个全中才死锁,破坏任一即预防。互斥/不剥夺是资源固有属性难改,预防主要从占有等待、循环等待下手。

二、四种处理策略对比

策略核心思想死锁是否发生代价适用场景
预防破坏四条件之一绝不发生资源利用率与并发度低实时/嵌入式、资源种类少
避免分配前判断是否进入不安全状态(银行家)不发生需预知最大需求、每次分配要运算资源需求可预知的批处理/数据库
检测恢复允许发生,周期检测后恢复可能发生检测开销、恢复时杀进程/回滚数据库事务死锁
鸵鸟忽略,假装不会发生可能发生偶发死锁需人工重启Linux/Windows 通用 OS

严格度:预防 > 避免 > 检测 > 鸵鸟(越严格越不死锁,但代价越大)。

三、银行家算法步骤

四个数据结构(资源类数 m、进程数 n):

名称类型含义
Available长度 m 向量各类资源当前剩余可用数
Maxn×m 矩阵每个进程对每类资源的最大需求
Allocationn×m 矩阵每个进程当前已分配到的资源
Needn×m 矩阵还可能申请的资源 = Max − Allocation

请求处理(Pi 申请 Request[i]):

1. 若 Request[i] > Need[i]:报错(超声明)
2. 若 Request[i] > Available:Pi 等待(资源不足)
3. 试探分配:Available −= Request[i]; Allocation[i] += Request[i]; Need[i] −= Request[i]
4. 跑安全性算法:
     安全 → 正式分配
     不安全 → 回滚试探,Pi 等待

安全性算法

Work = Available(可用工作向量)
Finish[i] = false(所有进程未完成)
循环:
  找一个 Finish[i]==false 且 Need[i] <= Work 的进程 Pi
  若找到:Work += Allocation[i](Pi 完成,归还资源); Finish[i] = true
  若找不到:跳出
若所有 Finish[i]==true → 安全(有安全序列)
否则 → 不安全

四、死锁 vs 饥饿 vs 活锁

死锁饥饿活锁
状态永久阻塞,不动可调度,长期无资源在运行,无进展
是否阻塞
原因互相等待对方资源调度不公(优先级低)互相让步响应
例子两把锁互等SJF 下长作业等不到 CPU走廊相遇同步让路
自行恢复可能可能(随机退避)
CPU 占用不一定可能高

关系:死锁一定伴随饥饿,饥饿不一定是死锁。活锁更隐蔽(监控看线程"活着"但产出为零)。

五、易错点清单

  • "四个条件满足就一定死锁":错。四条件是必要条件(全满足才可能死锁),但多实例资源时还需循环等待实际成立才死锁(有环不一定死锁)。
  • "资源分配图有环就是死锁":错。只有每类资源单实例时"有环⇔死锁";多实例有环不一定死锁,需图化简。
  • "不安全状态就是死锁":错。不安全只是有死锁风险(可能找不到安全序列),不一定真的死锁——可能后续请求恰好能被满足。银行家是保守地拒绝进入不安全状态。
  • "破坏任一条件都能预防死锁":对(四条件是必要条件),但破坏互斥/不剥夺往往不可行(资源固有属性),实际多破坏占有等待或循环等待。
  • "银行家算法能用在所有 OS":错。它要求预知每个进程最大需求,通用程序无法预估,且每次分配运算开销大,通用 OS 不用
  • "Linux 用银行家算法避免死锁":错。Linux/Windows 用鸵鸟策略(忽略死锁),不预防也不避免。
  • "饥饿就是死锁":错。饥饿进程还能被调度(只是轮不到资源),死锁进程永久阻塞。死锁一定饥饿,反之不然。
  • "活锁是死锁的一种":错。活锁进程没阻塞、在运行(互相让步),死锁进程完全卡死。两者都无进展,但机理不同。
  • "资源有序分配破坏了互斥":错。资源有序分配破坏的是循环等待(让请求方向单调,成不了环),不是互斥。
  • "死锁能自己解开":错。死锁是永久的,不会因多等而消失,必须外部干预(杀进程/抢占/重启)。

六、进阶方向(链接其他叶)

权威链接