文章目录
1死锁问题
死锁定义:
- 一个 进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件。称该进程是死锁的。
- 由于竞争资源或通信关系,两个或更多进程在执行中出现,导致两个进程因为访问的共享资源互斥被永远阻塞并互相等待,所引发的事件。一组阻塞的进程持有一种资源等待获取另一个进程所占有的一个资源。死锁导致的原因是并发。
eg:交通
- 每个车只能往一个方向运行
- 桥的两部分是两个资源
- 死锁需要一辆车倒退解决(抢占资源和回滚)
- 发生死锁可能需要倒退几辆车
- 有可能发生饥饿
2系统模型
2.1建模
包括需求方(进程),以及相关的资源
2.2资源
2.2.1资源定义:需要排他性使用的对象
资源类型:R1、R2、R3…,Rm
- 包括硬件外设以及软件数据结构,比如CPU、内存空间、I/O、数据库等
- 每个资源类型可能有多个实例
- 使用包括:request/get、use/hold、release
2.2.2资源分类:
- 可重用资源 :资源不能被删除,在任何时刻只能有一个进程使用,进程释放资源后,其他进程可重用,可能出现死锁。
示例:
- 硬件:处理器、IO通道、主副存储器、设备等
- 软件:文件、数据库和信号量等数据结构
- 消耗资源:资源的创建与销毁,一个进程产生,另一个进程使用。可能出现死锁,比如通信双方相互等待对方的消息。
示例:
- IO缓冲区的中断、信号、消息等。
2.3资源分配图:
- 结论:没环没死锁,有环每个资源只有一个实例就会死锁,每个资源有几个实例,可能死锁。
Pi->Ri:表示请求
Ri->Pi:表示使用/分配
eg:
无死锁
有死锁:有环出现P1->R1->P2->R3->P3->R2->P1以及P2->R3->P3->R2->P2
有循环的资源分配没有死锁:P1->R1->P3->R2->P1
注:P1指向R1的意思是,得到R1里任意一个实例都可以
3死锁特征
死锁出现必要不充分条件:
- 互斥:一个时间内只能有一个进程使用资源
- 持有并等待:进程保持至少一个资源正在等待获取其他进程持有的额外资源
- 无抢占:进程完成了他的任务之后,资源只能被进程自愿释放
- 循环等待:存在等待队列,P0等P1资源,P1等P2资源。。。PN等P0资源。
4死锁处理方法
4.1处理策略:
策略强度依次增强:
-
- 鸵鸟算法:忽略这个问题,假装系统中从来没有发生死锁,用于大多数操作系统,包括UNIX。
-
- 运行系统进入死锁状态,检测死锁状态然后恢复:死锁检测与死锁恢复
-
- 仔细进行资源分配,动态避免死锁:死锁避免
-
- 破坏死锁四个必要条件之一,防止死锁:死锁预防
4.2 死锁预防
方式:打破死锁出现的4个必要条件之一
- 互斥:把独占资源变为非独占资源。
- 占用并等待:进程执行前请求所需全部资源。
- 缺点:1.进程不知道自身需要多少资源 2.资源利用率低,可能会导致饥饿。
- 不可抢占:不可打破,影响互斥条件,比如kill进程
- 循环等待:消除环路
- 方案一:每个进程任一时刻只占用一个资源。(需要两个外设的按情况就会出现问题,不可使用)
- 方案二:对所有资源类型排序,要求每个进程按照资源顺序进行申请。(适合嵌入式操作系统)
4.3死锁避免
4.3.1方式
在申请资源时判断申请的资源是否合理。
4.3.2前提
需要系统具有额外先验信息。
- 要求进程声明它可能需要的每个类型资源的最大数目
- 通过某种方法限制提供和分配资源的数量,该数量不大于进程的最大需求。
- 通过算法动态检查不会出现环形等待。环形等待是不安全状态,不等于死锁状态。
安全状态和不安全状态:
- 安全状态:存在安全序列,从P1到Pn,按照序列执行每个资源都能得到满足。Pm进程运行时,Pm前资源(P1~Pm-1)都可使用
- 不安全状态:判断是否有环而不是是否死锁。不安全状态包含死锁,但不止死锁。
可以通过状态图判断
4.3.3银行家算法
思想
银行家向客户放贷,此时贷款必然收的回来(客户<->进程 资金<->资源)
前提
1.有多个实例
2.每个进程最大限度利用资源
3.当一个进程请求一个资源就不得不等待
4.当一个进程获得所有资源就必须在一段有限时间内释放他们
方法
寻址每个进程获得最大资源并结束的进程请求的一个理想执行时序,决定一个状态是否安全。
数据结构
n:进程数量, m:资源类型数量
- Max(总量需求):
n*m
矩阵。如果Max[i,j] = k,表示进程Pi最多请求资源类型Rj的k个实例。- Avaliable(剩余空闲量):长度为m的向量,Avaiable[j] = k,表示有k个类型的Rj资源实例可用
- Allocation(已分配量):
n*m
矩阵,Allocation[i,j] = k,则Pi以前分配了k个Rj实例- Need(未来需要量):
n*m
矩阵,Need[i,j] = k,Pi可能需要至少k个Rj实例完成任务。
Need[i,j] = Max[i,j]-Allocation[i,j]
安全性评估算法
//1.Work和Finish分别是长度为m和n的向量
//初始化:
work = Avaliable //当前资源剩余空闲量
Finish[i] = false for i (i = 1,2,3,...,n) //线程i没结束
queue q;
//2.找Need小于Work的进程i
next: Finish[i] = false;
if(Needi<=Work){//转3
//3.资源配置使用后回收
Work = work + allocationi;
Finish[i] = true; //可以运行
q.push_back(i);
goto next; //转2
}
else{ //转4
if(Finish[i]==true for all i){
//system is in a safe state
}
else{
//system is in an unsafe state
}
}
eg:4个进程,3个资源(P2->P1->P3/P4)
1.找小于Available[0,1,1]的Needi9(P2),所以从P2开始
缺点
时间复杂度大,需要O(m*n^2),还需要先验知识
4.4死锁检测
概念
一般用来调试程序,允许进入死锁状态,检测到死锁后,采取措施恢复。
死锁检测方法:
方法
1.简化资源图,只留下进程结点。检查进程之间是否存在循环。(O(n^2))
2.资源分配图
类似安全性能评估算法,判断i之后所有进程Need是否小于Avaliable。O(m*n^2)
使用
1.多久检测一次
2.回复方法
3.注意可能有多个循环
4.5死锁恢复
方法:
1.依次杀死进程直至进程恢复
依据
1.进程优先级
2.进程时间
3.占用资源
4.完成需要资源
5.进程中止数目
6.进程属性(交互/批处理)
2.资源抢占:临时将某个自愿从它当前所使用者那里转移给另一个进程
(批处理,需要人工干预)
3.资源回滚:返回到之前的安全状态