3.8 死锁的检测与解除

L21

学习目标

死锁有四个必要条件;预防、避免(银行家)、检测与解除是四条路。MCU 固件里更常见的是两个任务互相等锁——用设计避免,而不是上完整检测器。

  • 四条件:互斥、占有且等待、不可抢占、循环等待。破坏任一条件即可预防。
  • 银行家算法用安全序列避免进入不安全状态,实现代价高,适合动画理解。
  • 固件实例:任务 A 持 UART 锁等 GPIO,任务 B 持 GPIO 锁等 UART。超时放弃是工程折中。

原理 · 深入理解

3.8 死锁的检测与解除

本节概览:先建立「死锁的检测与解除」的框架,再依次展开下列小节。

  1. 死锁的检测
  2. 死锁的解除

3.8.1 死锁的检测

资源分配图由结点集 N 和边集 E 组成 G=(N,E)。

  1. N 分为进程结点集 P 和资源结点集 R
  2. 边 e∈E 连接 P 和 R 中的结点:请求边(Pi→Rj)和分配边(Rj→Pi)

利用资源分配图简化来检测系统是否处于死锁状态:找出既不阻塞又非独立的进程结点 Pi,让它获得资源运行至完成并释放资源,相当于消去其请求边和分配边,使之成为孤立结点。

图3-20 资源分配图的简化 P1 P2 R1 R2 能要到资源的边先拿掉,看还剩不剩环
图3-20 资源分配图的简化

简化过程:P1 释放资源后可使 P2 获得资源继续运行,P2 完成后释放资源形成图 (c)。

若能消去所有边使所有进程结点成为孤立结点,则图是可完全简化的(无死锁);否则不可完全简化(有死锁)。

死锁检测的数据结构类似于银行家算法。

  1. 可利用资源向量 Available,表示 m 类资源每类的可用数目
  2. 把不占用资源的进程(Allocation=0)记入 L 表

3.8.2 死锁的解除

死锁解除的两种方法。

终止所有死锁进程

最简单的方法,但代价可能很大,有些进程可能已接近结束。

逐个终止进程

按某种顺序逐个终止进程直至有足够资源打破循环等待,但每终止一个进程都有代价。

付出代价最小的死锁解除算法:基于进程的代价(如优先级、已运行时间、还需时间等)选择代价最小的进程终止,直至解除死锁。

图3-21 付出代价最小的死锁解除算法 选牺牲者 回退 / 终止 恢复运行 尽量少杀进程、少丢工作
图3-21 付出代价最小的死锁解除算法

做 · 交互动画

  • 根据「学习目标」列出 3 个关键词,对照原理段落解释给自己听。

死锁的检测与解除

用控件单步操作;日志区记下每一步发生了什么。

总结与提升

  • 能默写死锁四条件,并举一个固件中的例子。
  • 能用自己的话复述学习目标,并指出概念与板上实验的对应。

延伸思考

  • 超时放弃算不算「解除死锁」?
  • 如果把本节机制拿到 Linux 或完整 OpenHarmony 上,会多出哪些硬件假设?

← 本阶段封面 · 课程列表