死锁、死锁避免、银行家算法
1.概念
实例:
进程访问资源的流程:
现代大多数操作系统会选择忽略死锁,因为死锁出现的概率比较低,实在不行就重启。。。
2.建模
两类顶点:进程(圆形表示)和资源(方形表示);
使用有向边表示资源与进程之间的关系:
- 由进程指向资源的边表示进程申请资源;
- 由资源指向进程的边表示资源被进程占用。
3.死锁的产生条件
下面四个条件必须同时满足才可能出现死锁:
2)占有和等待条件是说已经占有一个资源的进程还需要等待其他资源才能完成。
举例:
右侧的图形虽然有环,但是不构成死锁。P2与P4任何一个执行完成都能使得其余进程拥有足够的资源。
4.死锁处理方法
4.1 死锁预防
破坏死锁发生的四个条件之一,但是会造成资源利用率低。
4.2 死锁避免
4.2.1 安全序列
分配资源之前先判断是否会造成死锁,如果死锁就不分配。
分配资源时根据动态检查结果决定是否分配资源。
系统是如何判断安全状态的呢?
如果序列p1,p2…pn是安全的,那么要求pi需要的资源<当前资源+它之前的进程拥有的资源;
对于p1,如果当前可用的资源不少于p1所需的资源,那么p1可以执行;
对于p2,如果当前资源以及p1拥有的资源不小于p2所需的资源,那么p2可以执行。
4.2.2 银行家算法
银行家算法是一种死锁避免的方法。目的是通过能否找到一个或多个安全序列来决定是否满足当前线程的资源请求。如果能找到安全序列,则可以将资源分配给请求的线程,且不会产生死锁,否则会死锁,安全序列不一定唯一。
available表示当前剩余资源的量;
allocation表示每个进程已经分配的资源的量;
max表示每个进程总共需要的量;
need表示每个进程还需要的量;
故:need=max-allocation。
银行家算法中的安全状态判断方法如下:
安全状态判断的目的是为了寻找一个安全序列。
work表示当前系统资源剩余量,每个线程结束后会改变。
第2)步,如果第i个线程Ti没有结束(Finish[i]=false):
- a)if( Need[i] <= Work ),表示当前资源足够Ti使用,那么将Ti的资源回收(Work = Work + Allocation)并继续寻找下一个线程。
- b)if( Need[i] > Work ),表示当前资源不够Ti使用,那么如果将Ti加入序列中,该序列不是安全序列,直接放弃此次寻找。
银行家算法的步骤:
银行家算法的目的是通过安全状态判断的结果决定是否将资源分配给发出请求的线程。
1)如果请求量Requesti小于等于需要的量,则转到2),否则拒绝(请求量大于需要的量,要多了);
2)如果请求量Requesti小于等于系统剩余量,则转到3),否则需要等待(因为资源暂时不够用);
3)通过安全状态判断结果决定是否分配资源,如果安全状态判断结果为安全,则可分配,否则不可分配。
举例参考:
https://blog.****.net/qq_34902437/article/details/82936161
https://blog.****.net/qq_33414271/article/details/80245715
4.3 死锁检测与恢复
死锁检测允许死锁现象的出现。
死锁检测方法与银行家算法相似,关键是检测到死锁之后的处理。
死锁检测的时间复杂度比较高,所以不能太频繁。
死锁恢复可以通过终止进程,回滚进程。
但是终止哪个进程不好判断,而且进程回滚实现起来太复杂了。