入门:死锁定义、四条件与饥饿/活锁
基于通用操作系统概念 · 核于 2026-08
速查
- 死锁定义:一组进程互相等待对方释放资源,每个进程都被阻塞、谁也无法前进的永久僵局——经典场景是两个进程各持一把锁、又去抢对方的锁,结果双双卡死。
- 本质:资源竞争 + 请求顺序不当。死锁不是 bug(逻辑没错),而是资源管理策略出了问题。
- 四必要条件(Coffman):①互斥(资源一次只能给一个进程用);②占有并等待(拿着资源不放,同时申请新资源);③不剥夺(资源不能被强行抢走,只能持有者主动释放);④循环等待(存在进程间的环形等待链)。四个全满足才会死锁,破坏任一即预防。
- 死锁 vs 饥饿:死锁是永久阻塞、卡死不动(等一个永远不会来的事件);饥饿是还能调度、只是轮不到资源(如低优先级进程总被抢占,长期得不到 CPU)。死锁一定伴随饥饿,饥饿不一定是死锁。
- 死锁 vs 活锁:活锁(livelock)是进程没有阻塞、还在运行,但因互相让步而都无法前进——两人走廊相遇互相让路、结果同步左右换位仍撞上。活锁在动,死锁不动。
- 资源分配图(RAG):进程与资源的有向图,有环不一定死锁——只有每类资源只有 1 个实例时"有环即死锁";多实例时要化简图(删掉能完成的进程)后看是否还有环。
- 四种处理策略:预防(破坏四条件)、避免(银行家算法)、检测与恢复(允许发生再处理)、鸵鸟(忽略,Linux/Windows 实际做法)。
- 进阶顺序:死锁四条件与资源分配图 → 死锁处理:预防、避免、检测 → 参考。
一、死锁是什么:永久阻塞的僵局
死锁(Deadlock)的经典定义:在一组进程中,每个进程都无限期等待只能由同组另一进程释放的事件(通常是资源)。结果是这组进程全部卡死,谁也走不到下一步。
最经典的例子是"两把锁":
线程 A: 线程 B:
lock(lock1); lock(lock2);
// 持有 lock1 // 持有 lock2
lock(lock2); ← 卡死在这 lock(lock1); ← 卡死在这
// 等 B 释放 lock2 // 等 A 释放 lock1- A 持有 lock1 等 lock2,B 持有 lock2 等 lock1——两人互相等对方手里的锁,谁也不松手,死锁。
- 特征:程序卡死不动、CPU 占用通常很低(都在 sleep/等待)、不报错、不崩溃,但业务彻底停滞。
死锁与一般"卡顿"的区别:死锁是永久的,不会因多等一会而自行解开(除非有外部干预——杀进程、超时)。
二、四必要条件:缺一不可
Coffman(1971)指出死锁发生必须同时满足四个条件,称为四必要条件:
- 互斥(Mutual Exclusion):涉及的资源是排他性的,同一时刻只能被一个进程占用(如打印机、写锁)。若资源可共享(如只读内存),则无需等待,不会死锁。
- 占有并等待(Hold and Wait):进程已占有至少一个资源,又在等待获取被其他进程占有的资源——持有不放的同时伸手要新的。
- 不剥夺(No Preemption):资源不能被强行夺走,只能由持有者主动释放。若可剥夺(如 CPU 可被调度器抢占),死锁可被打破。
- 循环等待(Circular Wait):存在一个进程的等待环
{P0→P1→...→Pn→P0},每个进程都在等下一个进程占有的资源。
- 为什么是必要条件:四个条件构成死锁的充要组合——任意破坏一个,死锁就不可能发生。这就是预防策略的依据(破坏其一即可)。
- 为什么"循环等待"最常被破坏:互斥/占有等待/不剥夺是资源的固有属性(打印机天然互斥),难改;而循环等待可以通过"资源有序分配"人为消除。
三、死锁 vs 饥饿 vs 活锁
这三者都是并发系统的病,但机理与表现不同:
| 死锁(Deadlock) | 饥饿(Starvation) | 活锁(Livelock) | |
|---|---|---|---|
| 状态 | 永久阻塞,完全不动 | 可调度,但长期得不到资源 | 在运行,但无进展 |
| 进程是否阻塞 | 是(都在 wait) | 否(可能就绪/运行) | 否(在反复让步) |
| 原因 | 互相等待对方的资源 | 调度策略不公(如优先级太低总被抢占) | 互相响应对方动作,反而都无法前进 |
| 经典例子 | 两把锁互等 | 短作业优先(SJF)下长作业永远等不到 CPU | 走廊相遇互相让路、同步换位仍相撞 |
| 是否自行恢复 | 否(需外部干预) | 可能(调度策略变化后可获资源) | 可能(随机退避后可解开) |
| CPU 占用 | 低(都在等) | 不一定 | 可能高(在空转让步) |
- 死锁一定伴随饥饿(被死锁的进程也"饿"着),但饥饿不一定是死锁(饥饿进程还活着、还能被调度,只是轮不到它)。
- 活锁比死锁更隐蔽:进程没卡住、监控看线程还"活着",但实际产出为零——分布式系统(如重传冲突)和锁让步(tryLock 失败立即重试)中常见。
下一步
理解了死锁的定义与四条件后,下一步深入死锁的识别工具——死锁四条件与资源分配图(如何用 RAG 判断系统是否死锁),以及四条件如何被破坏以实现预防。