Appearance
死锁的概念与预防
2026 大纲 二(四)1 死锁的基本概念 与 二(四)2 死锁预防。
互相等着对方手里的东西,谁也动不了
同步与互斥解决了"别互相踩",办法是排队等。可"等"这件事本身又带出了新问题。
看一个最小的例子:P1 拿着资源 A、想要 B;P2 拿着 B、想要 A。 两个人都在等,而对方手里那份资源只有对方肯放才会有——于是谁也动不了。 这就是死锁:一组进程都在等待只有组内其它进程才能引发的事件。
⚠️ 先划三条边界,它们经常被混起来:
死锁 vs 饥饿:死锁至少两个进程、且都处于阻塞态、图上有环; 饥饿可以只有一个进程、它处于就绪态(一直排不上而已)、没有环。 看进程数、看进程态、看有没有环,三条一比就分开了。
哪些资源会引起死锁:⚠️可抢占资源(CPU、主存)不会——抢过来就是了。 会引起的是不可抢占资源(打印机)与可消耗资源(消息:等一条永远不会来的消息)。
接下来是四个必要条件:互斥、请求和保持、不可抢占、循环等待。
⚠️ 这四条缺一不可,但必要而不充分——四条全满足也未必真死锁。 最干净的反例是同类资源备够
处理死锁的四种方法按防范程度递减、资源利用率递增: 预防 → 避免 → 检测 → 解除。而预防里有一条限制要先立住: 互斥这一条不能碰——它是资源本身的物理属性,破坏了就不叫互斥资源了。
一、死锁的定义与辨析
死锁、饥饿、死循环都表现为"程序没有正常推进",但成因与责任方完全不同:
| 死锁 | 饥饿 | 死循环 | |
|---|---|---|---|
| 涉及进程数 | 一组(至少 2 个) | 单个进程即可 | 单个进程 |
| 进程处于什么态 | 全部阻塞 | 就绪或阻塞,一直轮不到 | 运行(一直在跑) |
| 直接成因 | 互相等待对方持有的资源,形成环 | 资源/处理机的分配策略不公平 | 程序逻辑错误 |
| 例子 | 五位哲学家各拿一根筷子 | 读者优先方案里的写者;短作业优先里的长作业 | 循环条件永远为真 |
| 占用处理机吗 | 不占(都阻塞了) | 不占 | 占满 |
| 操作系统能否检测 | 能——有死锁检测算法 | 难——"等多久算饿死"没有客观界限 | 不能——无法判断是不是有意为之 |
| 谁负责 | 操作系统的资源分配 | 操作系统的调度/分配策略 | 用户程序 |
三条速判:看进程数(一个 or 一组)、看进程态(跑着 or 阻塞)、看有没有环。
二、四个必要条件
产生死锁必须同时具备下面四条,任一条不成立死锁就不会发生:
| 条件 | 教材表述 | 一句话理解 |
|---|---|---|
| 互斥条件 | 进程对所分配到的资源进行排它性使用,某资源在一段时间内只能被一个进程占用 | 资源不能共享 |
| 请求和保持条件 | 进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放 | 手里攥着还要再拿 |
| 不可抢占条件 | 进程已获得的资源在未使用完之前不能被抢占,只能在进程使用完时由自己释放 | 拿到就夺不走 |
| 循环等待条件 | 存在一个进程—资源的循环链:P₀ 等 P₁ 占用的资源、P₁ 等 P₂ 占用的资源、……、Pₙ 等已被 P₀ 占用的资源 | 等待关系首尾相接 |
四条是从"已经发生的死锁"里归纳出来的共性,所以是必要而非充分。
三、三类成因
| 成因 | 场景 | 关键点 |
|---|---|---|
| 竞争不可抢占资源 | P₁、P₂ 都要写文件 F₁ 与 F₂,各自先打开一个再去要另一个 | 🔴 同样两段代码,交错方式不同,一种正常一种死锁——死不死锁取决于推进的时机 |
| 竞争可消耗资源 | 三个进程互发消息,都先 receive 后 send | 死锁不必有资源实体,等待一个永远不会发生的事件同样构成死锁 |
| 进程推进顺序不当 | 一台打印机 R₁、一台磁带机 R₂ 供 P₁、P₂ 共享,两者交叉推进 | 进入不安全状态:还不是死锁,但再往前走可能死锁 |
三类成因的完整例子(想看清"合法推进"与"非法推进"分别怎么走时展开)
(1)竞争不可抢占性资源。 两个进程 P₁、P₂ 都要写文件 F₁ 和 F₂:P₁ 先打开 F₁ 再打开 F₂,P₂ 先打开 F₂ 再打开 F₁。
- 若 P₁ 先把两个文件都打开、P₂ 再来,P₂ 只是被阻塞,P₁ 关闭后 P₂ 就能继续——能正常运行
- 但如果 P₁ 打开 F₁ 的同时 P₂ 打开 F₂,每个进程都占有一个打开的文件;此时 P₁ 试图打开 F₂、P₂ 试图打开 F₁,两者都因文件已被打开而阻塞,它们希望对方关闭自己所需要的文件,但谁也无法运行——无限期等待,形成死锁
(2)竞争可消耗性资源。 三个进程用消息通信互相协作:P₁ 给 P₂ 发 m₁、P₂ 给 P₃ 发 m₂、P₃ 给 P₁ 发 m₃,同时每个进程又要接收上游发来的消息。
- 若三个进程都先 send 后 receive,则消息都能发出去、也都能收到,顺利运行
- 若三个进程都先 receive 后 send,则三个进程会永远阻塞在 receive 上,等待一条永远不会发出的消息,于是发生死锁
(3)进程推进顺序不当。 只有一台打印机 R₁ 和一台磁带机 R₂ 供 P₁、P₂ 共享。由于进程运行具有异步性,推进顺序可能合法也可能非法:
- 合法:P₁ 依次 Request(R₁)、Request(R₂)、Release(R₁)、Release(R₂),然后 P₂ 才开始——两个进程顺利完成
- 非法:两者交叉推进,进入不安全区——此时 P₁ 保持了 R₁、P₂ 保持了 R₂,系统处于不安全状态;如果继续推进,P₁ 请求 R₂ 时阻塞、P₂ 请求 R₁ 时也阻塞,死锁发生
四、处理死锁的四种方法
| 策略 | 介入时机 | 思路 | 资源利用率 | 实现难度 |
|---|---|---|---|---|
| 预防死锁 | 系统设计阶段 | 设置限制条件,破坏四个必要条件中的一个或几个 | 最低 | 简单直观,已被广泛使用 |
| 避免死锁 | 每次分配前 | 不破坏必要条件,而在资源动态分配过程中防止系统进入不安全状态 | 中 | 中 |
| 检测死锁 | 事后周期性 | 允许死锁发生,靠检测机构及时发现 | 高 | 高 |
| 解除死锁 | 检测到之后 | 撤消一些进程、回收资源,分配给阻塞进程 | 高 | 高 |
教材点明了这张表的单调性:从(1)到(4)对死锁的防范程度逐渐减弱,但对应的是资源利用率的提高,以及进程因资源因素而阻塞的频度下降(即并发程度提高)。这条单调性就是选型判据——防得越死,资源浪费越多。
五、死锁预防:破坏后三个条件
| 破坏的条件 | 具体做法 | 主要代价 | 判据:什么时候适用 |
|---|---|---|---|
| 互斥 | 把独占设备虚拟成共享设备(SPOOLing) | 需要额外的缓冲与管理开销 | 仅当资源能被虚拟化时(打印机可以,磁带机不行);教材强调互斥"不仅不能改变,还应加以保证" |
| 请求和保持 | 协议一:运行前一次性申请全部;协议二:分阶段申请与释放 | 资源利用率低、可能饥饿 | 资源需求能事先全部说清;资源使用有明显阶段性时用协议二 |
| 不可抢占 | 申请不到就释放已持有的全部资源 | 前功尽弃、反复申请释放、可能无限推迟 | 仅适用于状态可保存恢复的资源(CPU、内存);刻录机、打印机这类"中途夺走会毁掉已完成工作"的设备不适用 |
| 循环等待 | 资源有序分配法:按序号递增申请 | 序号难调整、限制编程自主性、部分资源被提前占用 | 通用,且资源利用率与吞吐量最好;系统资源类型相对稳定时最合适 |
资源有序分配法(也叫按序分配法、资源有序编号法)是最实用的一种:对所有资源类型线性排序、赋予唯一序号
序号怎么定:按大多数进程使用资源的先后顺序——一般先输入、再运算、最后输出,所以输入设备序号低、输出设备序号高。
破坏「请求和保持」的两种协议:教材原文与磁带—磁盘—打印机的例子(想弄清两种协议各自的取舍时展开)
第一种协议:所有进程在开始运行之前,必须一次性地申请其在整个运行过程中所需的全部资源。若有一种资源不能满足,即使其它资源都空闲也不分配,让该进程等待。
- 优点:简单、易行且安全
- 缺点 ①:资源被严重浪费。有些资源可能仅在运行初期或快结束时才使用,甚至根本不使用,却从头占到尾
- 缺点 ②:进程经常会发生饥饿。仅当获得全部资源后才能开始运行,个别资源(如打印机)长期被占用就会让进程迟迟不能启动
第二种协议(对第一种的改进):允许进程只获得运行初期所需的资源便开始运行;运行过程中逐步释放已用毕的资源,然后再请求新的资源。
教材的例子:一个进程要"磁带 → 磁盘排序 → 打印"。第一种协议下它开始时就得同时握住磁带机、磁盘文件和打印机,而打印机要到最后才用;第二种协议下它先只申请磁带机和磁盘文件,复制排序完就把它们释放,再去申请磁盘文件和打印机。
- 收益:进程更快完成、设备利用率提高、减少饥饿的几率
- 选哪种:资源使用阶段划分不清、或进程运行时间很短时用第一种(简单);资源使用有明显阶段性(前期用 A、后期用 B)时用第二种
破坏「不可抢占」的两条代价:① 实现复杂,打印机、刻录机这类资源被抢占后可能造成进程前一阶段工作失效,即使采取防范措施也会使进程前后两次运行的信息不连续;② 可能因反复申请和释放使进程执行被无限推迟,延长周转时间、增加系统开销、降低系统吞吐量。
有序分配法的三条局限:各类资源的序号必须相对稳定,限制了新类型设备的增加;作业实际使用资源的顺序常与系统规定的顺序不同,造成资源浪费;限制用户编程的自主性。教材对它的评价是"其资源利用率和系统吞吐量都有较明显的改善"。
六、从预防走向避免
预防是"一刀切"地砍掉某个必要条件,资源利用率最低。避免死锁不破坏任何必要条件,而是在资源动态分配过程中防止系统进入不安全状态。教材的评价是:这种方法所施加的限制条件较弱,可能获得较好的系统性能,目前常用此方法来避免发生死锁。安全状态与安全序列的完整定义、判定算法与手算步骤见银行家算法。
考点速记
- 死锁是"一组进程都在等待只有组内其它进程才能引发的事件"。
- ⚠️可抢占资源(CPU、主存)不会引起死锁;会引起的是不可抢占资源与可消耗资源(消息)。
- ⚠️死锁 / 饥饿 / 死循环的三条速判:看进程数(死锁至少两个)、看进程态(死锁是阻塞态,饥饿是就绪态,死循环是运行态)、看有没有环(只有死锁有)。
- 四个必要条件:互斥、请求和保持、不可抢占、循环等待,缺一不可。
- ⚠️必要而不充分:同类资源备够
份时( 个进程、每个最多要 个),四条照样成立却永不死锁——总有一个人能凑齐。这个公式是这一节所有计算题的唯一依据。 - 四种处理方法按防范程度递减、资源利用率与并发程度递增:预防 → 避免 → 检测 → 解除。
- ⚠️预防时互斥不能碰——它是资源的物理属性。最实用的是破坏循环等待的资源有序分配法,其无环性来自"持有序号单调递增"。
- 死锁可以通过剥夺资源解除;预防方法能确保系统不发生死锁(它从条件上就堵死了),而避免方法只是不让系统进入不安全状态。
这一节在真题里被考过的形式:
deadlock 挂了 13 道题,其中 6 道是银行家算法的计算(在银行家算法讲)、 1 道是哲学家大题。落在本节的有 5 道,而且计算题全部只用速记第五条那一个公式:
- ① 由资源总数反推最多几个进程不死锁,或反推最少要几份资源(2009-25、2014-24、2021-31)。三道题是同一个公式的三种问法。2009-25:8 台打印机、每个进程最多用 3 台,求不死锁的最大进程数
——由 总数 得 ,故 , 。⚠️ 做题时先分清题目给的是总数求进程数还是进程数求总数,公式同一个,解的未知量不同。 - ② 判断循环等待所需的最少进程数(2016-25)。3 类资源被 4 个进程竞争,问最少几个进程参与才可能形成环——判据是环至少要两个结点,再结合"每个进程最多持有几类"推。
- ③ 判断死锁的性质(2019-30、2015-26)。2019-30 答可以通过剥夺资源解除死锁 + 预防方法能确保系统不发生死锁。2015-26 比较死锁避免(S1)与死锁检测(S2):⚠️ 关键差别是S1 需要进程运行所需的资源总量信息(
Need),S2 不需要;而"限制申请顺序"是预防(资源有序分配法)的做法,避免并不限制顺序。
复习优先级:必须拿满,计算题只有一个公式。
易错:认为四个必要条件全满足就一定死锁。必要不充分——资源够多时四条成立也不会死锁。
易错:认为可以通过破坏"互斥"来预防死锁。互斥是资源的物理属性,不能碰。
易错:把死锁和饥饿混为一谈。死锁至少两个进程、处于阻塞态、有环;饥饿可以只有一个、处于就绪态、无环。
易错:认为 CPU 和主存也会引起死锁。它们是可抢占资源,抢过来就是了。
易错:认为死锁避免也会限制资源申请顺序。限制顺序的是预防(资源有序分配法),避免只做安全性检查。
易错:认为死锁检测也需要知道进程的资源总需求。只有避免(银行家)需要
Need,检测只看当前的Request。
教材出处
- 资源分类:汤小丹《计算机操作系统》3.5.1 节,印刷 p105——"CPU 和主存均属于可抢占性资源。对于这类资源是不会引起死锁的";不可抢占性资源举例为刻录机、磁带机、打印机;可消耗资源"最典型的……就是用于进程间通信的消息"。
- 三类成因:同书 3.5.2 节,印刷 p105—p107——竞争不可抢占资源(P₁/P₂ 交叉打开 F₁/F₂)、竞争可消耗资源(三进程都先 receive 后 send 则"永远阻塞在它们的 receive 操作上,等待一条永远不会发出的消息")、进程推进顺序不当(图 3-14 的合法与非法推进)。
- 死锁定义与四个必要条件:同书 3.5.3 节,印刷 p107—p108——"如果一组进程中的每一个进程都在等待仅由该组进程中的其它进程才能引发的事件,那么该组进程是死锁的";四条件的完整表述。
- 四种处理方法与单调性:同书印刷 p108——"从(1)到(4)对死锁的防范程度逐渐减弱,但对应的是资源利用率的提高,以及进程因资源因素而阻塞的频度下降(即并发程度提高)"。
- 破坏请求和保持的两种协议:同书 3.6.1 节,印刷 p108—p109——第一种协议的两条缺点(资源严重浪费、"使进程经常会发生饥饿现象")与第二种协议的磁带—磁盘—打印机例子。
- 破坏不可抢占与循环等待:同书 3.6.2、3.6.3 节,印刷 p109—p110——线性排序与
、 、 ;"规定每个进程必须按序号递增的顺序请求资源";"总有一个进程占据了较高序号的资源,此后它继续申请的资源必然是空闲的";以及"其资源利用率和系统吞吐量都有较明显的改善"与三条局限。 - 互斥条件不能破坏:同书 3.6 节开头,印刷 p108——"由于互斥条件是非共享设备所必须的,不仅不能改变,还应加以保证,因此主要是破坏产生死锁的后三个条件"。
- 避免死锁的定位:同书 3.7 节,印刷 p110——"这种方法所施加的限制条件较弱,可能获得较好的系统性能,目前常用此方法来避免发生死锁"。
相关知识
哲学家进餐问题|银行家算法|死锁检测与解除|SPOOLing 技术