最近开始学习操作系统原理这门课程,特将学习笔记整理成技术博客的形式发表,希望能给大家的操作系统学习带来帮助。同时盼望大家能对文章评论,大家一起多多交流,共同进步!
本文主要分以下几个方面:
- 系统模型(System Model)
- 死锁特征(Deadlock Characterization)
- 死锁的处理方式
- 死锁的预防(Deadlock Prevention) -- 设计无锁系统
- 死锁的避免(Deadlock Avoidance)
- 死锁的监测(Deadlock Detection)
- 从死锁状态恢复(Recovery from Deadlock)
死锁的定义:两个或两个以上进程由于竞争资源而导致系统无法推进,则称系统所处的状态为死锁。死锁为一种僵局。
举例:
系统有两个磁带设备(慢速设备,临界资源)
P1,P2各持有一个磁带设备并需要另一个
信号量A或B,初始化为1。
P0: P1: wait(A); wait(B); wait(B); wait(A);
下图为死锁的示意图:
死锁产生原因:
- 资源相对不足;
- 进程推进的次序不合理
必要条件:
- 互斥条件 Mutex exclustion:对资源的使用只能互斥不能共享
- 占有并等待 Hold and wait
- 非抢占/非剥夺 No preemption
- 循环等待/环路等待 Circular wait:系统对资源的申请和使用构成环路
故死锁为系统的一种可能性。
系统模型(System Model)
系统资源:R1,R2,...,Rm
CPU cycles, memory space, I/O device
每一个资源类型Ri都有Wi个实例。
每一个进程使用资源必须遵从:请求->使用->释放 的次序。
资源分配图(Resource-Allocation Graph)
一个由节点V和边E组成的集合
V可以分为两部分:
- P={P1,P2,...,Pn},系统进程构成的集合;
- R={R1,R2,...,Rn},系统资源构成的集合。
请求边:有向边 Pi -> Rj
分配遍:有向边 Rj -> Pi
资源分配图举例:该资源分配图未构成死锁,因没有环路
死锁的基本事实:
- 一个图不构成环路 -> 不构成死锁
- 图包含一个回路 ->
- 如果每个资源只有一个实例,则构成死锁
- 如果每个资源有不止一个实例,则有可能构成死锁
对待死锁的处理态度:
- 确保系统永远不会进入死锁状态
- 允许系统进入死锁状态,并处理死锁
- 忽略死锁问题并假定系统永不发生死锁
死锁的预防(Deadlock Prevention)
破坏死锁的四个必要条件之一,构建一个无死锁系统:互斥和非抢占无法破坏,可破坏占有并等待,即使用一次性资源分配法,缺点为资源浪费严重;可破坏环路等待,即使用有序资源使用法,经所有资源编号,只能按资源编号顺序申请
死锁的避免(DeadLock Avoidance)
执行一个死锁的避免算法来确保不会发生环路等待:银行家算法
每个进程声明美中类型资源的最大需求量,动态监测。
当一个进程请求一个可用资源时,系统必须确定分配该资源后系统是否处于安全状态。
安全状态:当所有进程都能存在安全序列时系统处于安全状态。
安全序列:即系统可以通过该序列合法调度所有进程。
银行家算法:
- 多实例
- 每一个进程预先声明最大的资源需求量
- 一个进程申请资源时可能等待
- 完成后释放资源
银行家算法的数据结构:
Available:m阶的数组,Available[j]=k表示j类资源还有k个;
Max: n*m的矩阵,Max[i,j]=k表示Pi类进程申请Rj类资源最多k个;
Allocation:n*m的矩阵,Allocation[i,j]=k表示Pi类进程已经占用Rj类资源k个;
Need:n*m的矩阵,Need[i,j]=k表示Pi类进程还需Rj资源k个 Need[i,j]=Max[i,j]-Allocation[i,j]
安全性算法:
- 假设Work和Finish为两个m维和n维的工作向量,初始化:Work:=Availble Finish:=false for i = 1,2,...,n
- 找满足以下条件:(a)Finish[i]=false; (b)Needi <= work; If no such i exists, go to step 4
- Work:= Work + Allocation; Finish[i]:=true; go to step 2
- If Finish[i]=true for all i, then the system is in a safe state
算法的主题过程
Requesti = request vector for process Pi. If requesti[j]=k then process Pi wants k instance of resource type Rj.
1. 合理性检查 If requesti <= Needi go to step 2; otherwise, raise error condition.
2. 预分配 If requesti <= Available, go to step 3; otherwise Pi must wait
3. 安全性检测
If safe => the resources are allocated to Pi
If unsafe => Pi must wait, and the old resource-allocation state is stored
死锁检测(Deadlock Detection)
- 允许系统进入死锁状态
- 检测算法
- 恢复机制
Maintain wait-for graph
- 节点为进程
- Pi->Pj表明Pi在等待Pj
系统周期性的调用算法判断图中是否有环路。
其过程(Available, Allocation, Request)类似于银行家算法。
调用该检测算法的频度和时间:
- 死锁发生的频率
- 有多少进程需要回滚
若检测方法被随意调度,则可能会出现多个环路,即多个进程进入危险区。
死锁的恢复(Detection Algorithm)
终止进程:可能会导致时间浪费或进程同步间的问题
终止在死锁状态的所有进程
每次终止一个进程知道死锁环路消除
选择终止的进程次序:
- 进程已运行时间和预计还需运行时间
- 优先级
- 进程已经使用的资源
- 进程完成还需使用的资源
- 解除死锁需要终止进程的数量
- 进程为交互性的还是批处理的
剥夺资源(Resource Preemption)
以最小成本寻找进程的牺牲者。
回滚:回退到某个安全时刻,在该进程重启进程
饥饿:有一些进程可能永远被选作牺牲者