一、核心概念

1. 死锁的定义

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象。若无外力干预,这些进程将永远无法继续执行。

2. 资源类型

理解死锁前,需要明确操作系统中资源的分类:

资源类型 含义 特点 示例
可剥夺资源 可被系统强制收回 不导致死锁 CPU、内存
不可剥夺资源 必须由持有者主动释放 可能引发死锁 打印机、文件锁
临时性资源 由进程产生,使用后被消耗 可能引发死锁 信号、消息
永久性资源 可重复使用,数量固定 主要死锁来源 I/O设备、存储空间

3. 死锁与饥饿的区别

对比项 死锁 饥饿
进程状态 至少两个进程相互等待,全部阻塞 单个进程长期得不到资源
发生原因 资源分配不当,形成循环等待 调度策略不公平
解决难度 必须打破循环等待链 调整优先级即可解决
类比 两人互拿对方需要的筷子,都不放手 一个人总被插队,永远轮不到

死锁是"同归于尽",饥饿是"单方面受难"。死锁至少涉及两个进程,饥饿可能只有一个"倒霉蛋"。

在这里插入图片描述

二、死锁产生的四个必要条件

死锁的发生必须同时满足以下四个条件,缺一不可:

条件 含义 说明
互斥条件 资源一次只能被一个进程使用 打印机、临界区等天然具有互斥性
请求与保持 进程持有资源的同时,又申请新资源 吃着碗里的,看着锅里的
不可剥夺 进程获得的资源不能被强制抢走 必须由持有者主动释放
循环等待 多个进程形成首尾相接的资源等待链 P1等P2,P2等P3,P3等P1

这四个条件中,互斥条件是资源的固有属性,无法破坏;循环等待是死锁发生时的最直观表现,但不等于死锁(是必要条件而非充分条件)。

死锁的判定逻辑

  • 四个条件全部满足必然发生死锁
  • 任意一个条件不满足不会发生死锁

三、死锁的处理策略

操作系统中处理死锁的策略分为三个层次:预防、避免、检测与恢复

策略 介入时机 核心思想 具体方法
死锁预防 系统设计阶段 破坏四个必要条件之一 静态分配、有序资源分配
死锁避免 系统运行阶段 动态判断是否进入不安全状态 银行家算法
死锁检测与恢复 死锁发生后 定期检测并强制解除 资源分配图化简、终止进程

在这里插入图片描述

1. 死锁预防

通过破坏死锁的四个必要条件之一来预防死锁:

破坏的条件 方法 优缺点
破坏"请求与保持" 静态分配:进程运行前一次性申请全部资源 资源利用率低,可能饥饿
破坏"不可剥夺" 进程申请新资源失败时,主动释放已持有资源 实现复杂,状态保存开销大
破坏"循环等待" 有序资源分配:给资源编号,进程必须按编号递增顺序申请 编号难以统一,限制并发度

2. 死锁避免——银行家算法

银行家算法,是典型的死锁避免算法。其核心思想是:每次分配资源前,先"试探性"地判断分配后系统是否仍处于安全状态

关键数据结构

  • Available:系统当前可用资源向量
  • Max:每个进程对各类资源的最大需求
  • Allocation:每个进程已分配的资源
  • Need:每个进程还需要的资源(Need = Max - Allocation)

安全状态的判定

  1. 假设某个进程能获得所需资源并运行完成
  2. 完成后释放其全部资源
  3. 判断是否存在一个安全序列,使所有进程都能顺利完成

"有钱才借,借了还得起。“银行家算法的本质是"稳健放贷”,只把资源借给能还款(能运行完)的进程。

3. 死锁检测与恢复

当系统不采取预防和避免策略时,需要具备检测和恢复能力。

检测方法

  • 构建资源分配图
  • 若能完全化简(消除所有边),则无死锁
  • 若存在无法化简的环路,则发生死锁

恢复方法

  • 进程终止:撤销所有死锁进程(代价大)或逐个撤销直到死锁解除
  • 资源剥夺:强制取走某些进程的资源,分配给其他进程
  • 回退:将进程回滚到死锁前的检查点重新执行

四、经典计算:不发生死锁的最小资源数

公式推导

设系统中有 n 个并发进程,每个进程需要 m 个同类资源

最坏情况:每个进程都拿到了 m - 1 个资源,都在等待第 m 个资源。

此时需要的资源总数 = n × (m - 1)

在此基础上再加 1 个资源,就能保证至少有一个进程可以拿到 m 个资源,从而运行完成并释放资源。

公式:不发生死锁的最小资源数 = n × (m - 1) + 1

推广形式

若系统中每个进程需要的资源数不同,设第 i 个进程需要 Ri 个资源,则:

不发生死锁的最小资源数 = (R1 - 1) + (R2 - 1) + … + (Rn - 1) + 1 = Σ(Ri - 1) + 1

让所有人都"差一个"是临界状态,再多一个就能打破僵局。类比一群人分苹果,每人想要N个,最惨的情况是每人先分到N-1个,这时再来一个苹果,必然有人凑够N个。

五、练习

题目1:以下关于死锁的必要条件的叙述中,错误的是( )。

A. 互斥条件:一个资源每次只能被一个进程使用
B. 请求与保持条件:一个进程请求资源失败时,需释放已占有的资源
C. 不可剥夺条件:进程获得的资源在使用完之前不能被强行夺走
D. 循环等待条件:若干进程之间形成头尾相接的循环等待资源关系

答案:B

解析:B错误,"请求与保持"条件是指进程在保持已有资源的同时请求新资源,而非请求失败时释放资源(释放资源恰恰是破坏该条件的手段)。

题目2:某系统中有5个并发进程,每个进程都需要4个同类资源。该系统不发生死锁的最少资源数是( )。

A. 12  B. 13  C. 16  D. 20

答案:C

解析:套用公式:n × (m - 1) + 1 = 5 × (4 - 1) + 1 = 5 × 3 + 1 = 16。

题目3:某系统采用银行家算法,当前状态如下表:

进程 Max Allocation Need Available
P0 7 5 3 0 1 0 7 4 3 3 3 2
P1 3 2 2 2 0 0 1 2 2
P2 9 0 2 3 0 2 6 0 0
P3 2 2 2 2 1 1 0 1 1
P4 4 3 3 0 0 2 4 3 1

以下哪个进程序列是安全序列?( )

A. P1, P3, P4, P0, P2
B. P1, P3, P0, P4, P2
C. P3, P1, P4, P0, P2
D. P1, P3, P4, P2, P0

答案:A

解析:

  1. 初始Available = (3, 3, 2)
  2. P1的Need = (1, 2, 2) ≤ Available,P1可完成,释放后Available变为(5, 3, 2)
  3. P3的Need = (0, 1, 1) ≤ Available,P3可完成,释放后Available变为(7, 4, 3)
  4. P4的Need = (4, 3, 1) ≤ Available,P4可完成,释放后Available变为(7, 4, 5)
  5. P0的Need = (7, 4, 3) ≤ Available,P0可完成,释放后Available变为(7, 5, 5)
  6. P2的Need = (6, 0, 0) ≤ Available,P2可完成

题目4:某系统中有R1、R2两种资源各2个,现有P1、P2两个进程。P1已获得1个R1,正在申请1个R2;P2已获得1个R2,正在申请1个R1。该状态是否发生死锁?( )

A. 是,因为满足死锁的四个必要条件
B. 否,因为可以通过剥夺资源解决
C. 是,但银行家算法可以避免
D. 否,因为资源申请可以被满足

答案:A

解析:P1持有R1等待R2,P2持有R2等待R1,形成循环等待。四个条件均满足,发生死锁。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐