操作系统的第二篇,翻死锁这座山。
死锁在上午题里占 1~2 分,考法高度固定:四个必要条件(概念)、最少需要多少资源才不死锁(套公式)、银行家算法判断安全序列(填表体力活)。这篇挨个拆透,顺便把"资源分配图有环"这个经典误会讲清楚。
一、什么是死锁?独木桥问题
一条只容一车通过的独木桥,两头各来一辆车,开到桥中间相遇——谁也不肯退,谁也过不去。双方都占着对方需要的东西,都在等对方先放手,于是永远僵住。这就是死锁:
两个或多个进程,互相等待对方占有的资源,结果所有进程都无法推进。
二、四个必要条件:缺一不可
死锁要发生,必须同时满足四个条件(上午题直接考):
互斥:资源一次只能一个进程用(独木桥一次只能过一辆车);
占有且等待:手里攥着资源不放,同时伸手要新的(车占着半座桥,还要对方那半座);
不可剥夺:资源不能被抢走,只能等占用者主动释放(谁也不能把对方推下桥);
循环等待:形成"你等我、我等他、他等你"的环形等待链。
四个条件缺一不可——所以预防死锁的思路就一句话:随便破坏一个:
| 破坏谁 | 怎么破坏 | 备注 |
|---|---|---|
| 占有且等待 | 进程开工前一次性申请全部资源,要不齐就不开工 | 资源利用率低 |
| 不可剥夺 | 申请不到新资源时,主动释放已占有的 | 实现麻烦 |
| 循环等待 | 资源编号,按序号递增申请 | 最常用,考点 |
| 互斥 | 基本破坏不了(资源本性) | 了解即可 |
"按序号递增申请"为什么能破环?你申请了 3 号资源,就永远不许回头要 2 号——等待链只能朝编号大的方向延伸,永远绕不回起点,环无从形成。
三、三种处理策略:概念题的分层
死锁预防:事前立规矩,破坏四条件之一(静态、保守);
死锁避免:资源分配前先算账,确认"这么分不会出事"才分——银行家算法就属于避免(高频考点:问银行家算法属于哪类策略);
死锁检测与解除:放任发生,事后查账,发现死锁再剥夺资源或撤销进程。
记忆:预防是"不许你危险",避免是"危险来临前刹车",检测是"出了事再救"。
四、最少多少资源才不死锁?一个公式
经典题型:n 个进程,每个进程最多需要 k 个同类资源,系统至少配多少个资源(m)才能保证不发生死锁?
m ≥ n × (k - 1) + 1
推导(懂了就不用背):想象最坏的情况——每个进程手里都捏着 k-1 个资源,都只差 1 个就能完工。此时共被占住 n×(k-1) 个资源。只要系统里还剩 1 个富余,这个资源无论给谁,那个进程就凑够了 k 个,跑完后把手里的 k 个全部释放,连锁反应,大家陆续解套。所以 n(k-1)+1 个就稳了;少一个,就可能全员捏着 k-1 个干瞪眼——死锁。
例:3 个进程、每个最多要 4 台打印机 → 3×3+1 =10 台。
五、银行家算法:安全序列是填出来的
银行家算法回答一个问题:当前这个分配方案下,系统还安全吗?(存在至少一条让所有进程都能跑完的序列,就安全。)
手里三张表:已分配 Allocation、还需求 Need、系统可用 Available。检查步骤就两步循环:
找一个Need ≤ Available的进程(它现在要的东西,系统给得起);
假设它跑完,Available 回收它的 Allocation(Available += Allocation),回到第 1 步。
所有进程都能排进序列 →安全;卡住了 →不安全(注意:不安全 ≠ 已经死锁,是"可能死锁",银行家因此拒绝分配)。
例题:系统有 A、B 两类资源,Available = (1, 2):
| 进程 | Allocation | Need |
|---|---|---|
| P1 | (2, 0) | (1, 2) |
| P2 | (0, 1) | (2, 1) |
先试 P1:Need(1,2) ≤ Available(1,2) ✓ → 假设跑完,Available = (1,2)+(2,0) =(3,2);
再看 P2:Need(2,1) ≤ (3,2) ✓ → 跑完,全部完成;
系统安全,安全序列<P1, P2>。
若先试 P2:Need(2,1) ≤ (1,2)?2>1 ✗,此路不通。所以序列唯一:P1→P2。考场上就是把这张表推演一遍,零技巧,纯体力。
六、资源分配图:有环 ≠ 死锁
资源分配图里,进程指向资源是"请求",资源指向进程是"占有"。有环不一定死锁:
每类资源只有一个实例:有环 = 死锁(独木桥场景);
资源有多个实例:有环也可能解开(环上某个进程的资源可能被环外的进程释放)。
这是软考爱挖的坑,记住"单实例有环必死锁,多实例有环不一定"。
七、10 道练习题
基础题(1~5)
1.死锁是指( )。
A. 进程被系统撤销 B. 多个进程互相等待对方占有的资源,都无法推进 C. CPU 长时间空闲 D. 内存容量不足
2.下列各项中,不是死锁产生必要条件的是( )。
A. 互斥 B. 占有且等待 C. 可剥夺 D. 循环等待
3.通过"破坏四个必要条件之一"来防止死锁发生的策略,称为( )。
A. 死锁预防 B. 死锁避免 C. 死锁检测 D. 死锁解除
4.银行家算法属于( )。
A. 死锁预防 B. 死锁检测 C. 死锁解除 D. 死锁避免
5.给系统内所有资源编号,规定进程只能按序号递增的顺序申请资源,该方法破坏的是( )。
A. 互斥 B. 循环等待 C. 占有且等待 D. 不可剥夺
进阶题(6~10,带坑)
6.系统中有 3 个进程,每个进程最多需要 4 台同类资源(如打印机),系统至少配备( )台才能保证不发生死锁。
A. 12 B. 10 C. 9 D. 13
7.系统中有 5 个进程,每个进程最多需要 3 个同类资源,系统至少配备( )个资源才能保证不发生死锁。
A. 15 B. 10 C. 11 D. 6
8.某时刻系统可用资源 Available = (1, 2),进程 P1 的 Allocation = (2, 0)、Need = (1, 2),P2 的 Allocation = (0, 1)、Need = (2, 1),则系统的安全序列是( )。
A. <P2, P1> B. 两个序列都安全 C. <P1, P2> D. 系统不安全
9.关于资源分配图与死锁的关系,下列说法正确的是( )。
A. 每类资源只有一个实例时,图中有环则必发生死锁 B. 图中只要有环,就必定发生死锁 C. 图中无环也可能发生死锁 D. 图中有环时,撤销环上任意一个进程即可解除死锁
10.关于死锁,下列说法错误的是( )。
A. 四个必要条件必须同时满足,才可能发生死锁 B. 银行家算法在分配资源前先检查系统是否仍处于安全状态 C. 破坏循环等待的常用方法是资源按序分配 D. 只要系统中存在循环等待,就一定发生了死锁
八、答案与详解
1. B死锁的关键词:互相等待、都无法推进。A、C、D 都是干扰,跟"循环等待资源"无关。
2. C四条件是:互斥、占有且等待、不可剥夺、循环等待。选项把"不可剥夺"换成了"可剥夺"——恰恰相反,能剥夺反而有助于破解死锁。
3. A破坏四条件 =预防(事前立规矩)。和"避免"的区别:预防是静态设限,避免是动态算账(分配前查安全性)。
4. D高频考点:银行家算法属于死锁避免——分配前先用安全性算法检查"分完之后系统是否还有安全序列",有则分,无则拒。
5. B按序递增申请,等待链只能朝大编号延伸,绕不回起点——破坏的正是循环等待。这是四种破坏法里软考唯一爱考的。
6. B套公式 n(k-1)+1 = 3×3+1 =10 台。选 A(12=3×4)的是直接乘了需求量——那是"人人同时拿满",过度富裕,不是"至少";选 C(9)的忘了"+1"那临门一脚。
7. Cn(k-1)+1 = 5×2+1 =11 个。再验一遍最坏情况:5 个进程各捏 2 个(共 10 个),第 11 个无论给谁,那人凑够 3 个跑完释放,连锁解套 ✓。
8. C填表推演:P1 Need(1,2) ≤ Available(1,2) ✓,跑完回收 → Available = (3,2);P2 Need(2,1) ≤ (3,2) ✓。安全序列<P1, P2>。而先走 P2:Need(2,1) ≤ (1,2) 不成立——所以序列唯一,选 B 的没有真的动手算。
9. A单实例资源 + 有环 = 必死锁;多实例时有环不一定(环外可能有人释放资源解套)。B 错在"只要……就";C 错,无环必无死锁;D 想当然,环上进程可能握着多份资源,撤一个未必解环。
10. D选"错误的":A、B、C 是正文原话。D 错——多实例资源存在循环等待时,仍可能由环外进程释放资源而解开;只有单实例场景下"循环等待 = 死锁"才成立。这是本篇前后呼应的同一个坑,考的就是你是否真的消化了。
九、五句话带走
死锁 =互相等待、谁也无法推进;
四条件缺一不可:互斥、占有且等待、不可剥夺、循环等待;预防 = 破坏其一;
银行家算法 = 死锁避免,分配前先查安全序列;
不死锁资源数:n(k-1)+1;
安全序列:找 Need ≤ Available → 回收 Allocation → 循环;单实例有环必死锁,多实例有环不一定。
下一篇预告:操作系统第三站——存储管理:分页式存储的地址转换、FIFO 和 LRU 页面置换的缺页率怎么算。给了页面访问序列,拿张纸画格子就能算分,但 LRU 的格子画法和 FIFO 有本质不同,错一步全错。