记录操作系统中死锁相关内容。
System Model
Notations:
- Threads T1, T2, …, Tn
- Resource types R1, R2, …, Rm
- e.g., CPU, memory space, I/O devices, mutex and semaphores
- Each resource type Ri has Wi instances.
定义:当一组线程中的每个线程都在等待仅由该组中其他线程引起的事件时,这组线程就处于死锁状态。这些事件主要包括资源的获取和释放。
eg. 双向车辆在一车道会车
Deadlock Characterization
同时满足以下四个条件导致死锁:
- Mutual Exclusion: 互斥,该时刻资源被一个线程独占
- Hold and Wait: 一个线程在等待另一个线程释放资源
- No Preemption: 一个线程不能抢占另一个线程的资源
- Circular Wait: 一组线程形成一个环,每个线程都在等待另一个线程释放资源
Resource-Allocation Graph
Resource-Allocation Graph (RAG) 是一个有向图,用于表示资源分配和请求的关系。
- 节点表示进程和资源
- 边表示进程对资源的请求和释放
Methods for Handling Deadlocks
- Never enters a deadlock
- 预防死锁 prevention
- 避免死锁 avoidance
- Detect and recover from deadlock
- 检测死锁 detection
- 从死锁中恢复 recovery
Deadlock Prevention
破坏四个条件之一:
- 互斥: 去除共享资源的互斥性
- 占有并等待: 一次性申请所有资源/仅在无任何资源才请求
- 不可抢占: 允许抢占资源
- 循环等待: 对资源进行排序
Deadlock Avoidance
需要额外信息支持:
- 每个进程对每种资源的最大需求
- 每种资源的可用数量
safe state:一个序列是安全的,如果对于每个进程,它可以在有限时间内完成,并且所需的资源可以被当前可用的资源和以前分配的资源满足
分配资源策略:当存在一个安全序列时,分配资源
resource-allocation-graph algorithm
- 相关概念:引入了新的概念——声称边(Claim edge),用有向虚线
Ti → Rj
表示线程Ti
可能请求资源Rj
。当线程请求资源时,声称边转换为请求边;资源分配给线程时,请求边转换为分配边;线程释放资源时,分配边重新转换为声称边(若线程结束,该边移除)。 - 算法核心判断:当线程
Ti
请求资源Rj
时,只有在将请求边转换为分配边后,资源分配图中不会形成圈的情况下,该请求才能被批准。若形成圈,则意味着可能出现死锁,请求不能被批准,线程需要等待。比如,若线程T1
请求资源R1
,在当前资源分配图的基础上,如果将T1
到R1
的请求边转换为分配边后,图中出现了T1 → R1 → T2 → R2 → T1
这样的圈,那么T1
对R1
的请求就不能被批准,T1
需等待
Banker’s Algorithm
银行家算法(Banker’s Algorithm)是一种著名的死锁避免算法。其名字的由来是因为该算法原本是银行用来分配资源的策略。
基本概念
数据结构
Available
: 长度为m的向量,表示每种资源的可用数量Max
: n×m矩阵,表示每个进程对各种资源的最大需求Allocation
: n×m矩阵,表示每个进程已分配的各种资源数量Need
: n×m矩阵,表示每个进程还需要的各种资源数量
其中,n为进程数,m为资源类型数
安全状态
系统处于安全状态意味着存在一个安全序列,使得所有进程能够按照这个序列顺序完成。
算法流程
1 |
|
Deadlock Detection
Single instance of each resource type: 维护一个等待图
Multiple instances of each resource type:
- available vector
- allocation matrix
- request matrix
1 |
|
核心算法:通过work向量和finish向量来判断是否存在死锁,循环迭代查找可完成进程
使用检测算法,要考虑死锁发生频率,回滚线程数量等开销
Recovery from Deadlock
- 终止进程: 终止一个/多个进程,直到死锁解除
- 抢占资源: 抢占一个/多个进程的资源,直到死锁解除