死锁
- 两个或者两个以上的进程在执行的过程中,由于竞争资源或者彼此通信而造成的阻塞现象,这些永远在相互等待的进程被称为死锁进程。
- 彼此通信是指:A等待B发来消息,B等待C发来消息,C等待A发来消息
- 资源分配图:
- 由进程->资源叫申请边,
- 资源->j进程叫分配边
- 圆形叫进程,圆点方形叫资源
- 无闭环就没有死锁
- 有闭环则可能存在死锁
死锁四个必要条件
- 互斥条件:进程对所分配的到的资源不允许其他进程访问,若其他进程访问该资源,只能等待,直到占有该资源的进程使用完成后释放该资源。
- 请求和保持条件(占有且申请):进程获得一定资源后,又对其他资源发出请求,但该资源可能被其他进程占用,此时请求阻塞,但进程又对自己获得的资源保持不放(占着茅坑不。。)
- (不可抢占):进程已经获得的资源,在未完成使用之前,不可被剥夺,只能在完成后自己释放
- 循环等待条件:进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系
- 这四个是必要条件,只要发生死锁,这些必要条件必然成立。但是是要上面有一个条件不成立,就不会发生死锁。(四个都成立才可能发生死锁)
- 同时具备这四个才会发生死锁,只要一个不具备就不会死锁
解决死锁的方法
死锁的预防
- 打破互斥:允许进程同时访问某些资源,但缺点是有些资源本身就没法同时访问
- 打破不可抢占:允许进程强行占用其他进程的某些资源。即当一个进程占有了一些资源,他又申请新资源时,如果申请不能立即满足,他必须释放之前占有的全部资源
- 打破占有请求:实行预分配,即进程在运行前一次性的像系统申请所需要的全部资源。如果得不到满足,则不分配任何资源。
- 缺点:进程是动态的,不可一次预测所需全部资源
- 资源利用率低,有些资源可能开始不需要用,但也被提前占了
- 降低并发
- 打破循环等待:把资源分类编号,所有进程对资源的申请必须按照资源序号递增的顺序提出。进程占用了小号码资源,才能申请大号码资源
- 缺点:编号困难增加了开销
- 为了严格按照编号次序申请,暂不使用的资源也需要提前申请
死锁的避免
- 死锁的避免是排除死锁的动态策略,他不限制进程有关申请资源的命令,而是对进程所发出的每一个申请资源命令加以动态检查,并根据检查结果决定是否进行资源分配。就是说,在资源分配过程中若预测有发生死锁的可能性,则加以避免。
- 安全序列:系统中·的所有进程能够按照某一种次序分配资源,并依次运行完毕,这种进程序列就是安全序列。如果存在这样一个安全序列,那么系统是安全的。
- 存在安全序列一定不会死锁,但是进入不安全状态(没有安全序列)也未必会产生死锁。
银行家算法
- 避免死锁的算法
- 分为安全检测算法和资源请求算法
- 下面是银行家算法的安全检测算法
Available[j],每种资源现有个数
Max[i][j],每种进程的最大需求
Allocation[i][j],每种进程已经分配的资源
Need[i][j],每种资源还需要的资源数
Need[i][j] = Max[i][j] - Allocation[i][j]
Work记载每种资源剩余的个数
Finish记录哪些进程通过了
//1.Work,Finish初始化
for(i<资源数){
Work[i] = Available
}
for(i<j进程数){
Finish[i] = false;
}
//2.找满足条件的进程(没遍历过的,且能满足资源需求)
if(Finish[i] == false && Need <= work[i])
else 没有这样的i跳到步骤4
3.刚才找到的进程置为true,且进程完了释放资源
Work = work + Allocation
Finish = true
4.如果所有finish都是true那么系统处于安全状态