1. 死锁、饥饿、死循环
-
死锁:各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象
-
饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象
-
死循环:某进程执行过程中一直跳不出某个循环的现象
-
共同点:都是进程无法顺利向前推进的现象
-
区别
- 死锁一定是“循环等待对方手里的资源”导致的,至少有两个或以上的进程同时发生死锁,并且发生死锁的进程一定处于阻塞态
- 可能只有一个进程发生饥饿,发生饥饿的进程有可能是阻塞态(等待I/O资源),有可能是就绪态
- 可能只有一个进程发生死循,发生死循环的进程可能是运行态
2. 死锁产生的必要条件
- 产生死锁必须同时满足一下四个条件,死锁才会产生
- 互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁
- 不剥夺条件:进程所获得资源在未使用完之前,不能由其他进程强行夺走,只能主动释放
- 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放
- 循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求,发生死锁时一定有循环等待,但是发生循环等待时未必有死锁
3. 发生死锁的情景
- 对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不引起死锁的
- 进程推进顺序非法。请求和释放资源的顺序不当,也同样会导致死锁。进程P1、P2需要对R1、R2进行访问;并发执行过程中,P1占用R1,请求R2;P2占用R2,请求P1
- 信号量的使用不当也会导致死锁
4. 死锁的处理策略
- 预防死锁。破坏死锁产生的四个必要条件的一个或几个
- 避免死锁。用某种方法防止系统进入不安全状态,从而避免死锁(银行家算法)
- 死锁的检查和解除。允许死锁的发生,操作系统负责检查出死锁并解除
5. 预防死锁
-
破坏互斥条件
- 把互斥使用的资源改造为允许共享使用,系统不会进入死锁状态。比如:SPOOLing技术
- 缺点:并不是所有的资源都能改造成可共享使用的资源,实际上,基本无法破坏互斥条件
-
破坏不剥夺条件
- 进程请求新的资源得不到满足时,它必须释放保持所有的资源
- 进程需要的资源被其他进程所有占用的时候,由操作系统协助强行剥夺
- 缺点:实现复杂;适用于易保存和恢复状态的资源,如CPU;反复申请和释放资源,增加系统开销,降低吞吐量;会导致进程饥饿
-
破坏请求和保持条件
- 采用静态分配方法,进程运行前一次申请完它所需的全部资源,在它的资源为未满足前,不让它投入运行。
- 缺点:资源利用率低,可能会导致某些进程饥饿
-
破坏循环等待条件
- 顺序资源分配法,规定每个进程必须按编号递增的顺序请求资源,同类资源一次申请完
- 缺点:不方便增加新的设备,需要重新分配编号;实际使用的顺序和编号顺序不一致,导致资源的浪费;必须要按规定次序申请资源,用户编程麻烦
6. 避免死锁
-
安全序列:如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。 如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁。因此可以在分配资源之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求,这也是“银行家”算法的核心思想
-
银行家算法
-
检查此次申请是否超过了之前声明的最大需求数
-
检查此时系统剩余的可用资源是否还能满足这次请求
-
试探着分配,更改各数据结构
-
用安全性算法检查此次分配是否会导致系统进入不安全状态
- 检查当前剩余可用资源是否能满足某个进程的最大需求,如果可以,就把进程加入安全序列,并把该进程持有的资源全部回收。不断反复上述过程,看最终是否能让所有进程加入安全序列
-
7. 死锁的检测和解除
-
死锁的检测
-
用某种数据结构来保存资源的请求和分配信息
-
数据资源图
- 两种节点:进程节点、资源节点
- 两种边:进程节点→资源节点(请求边)、资源节点→进程节点(分配边)
-
-
提供一种算法,利用上述信息来检测系统是否已进入死锁状态
-
死锁检测算法
- 依次消除与不阻塞进程相连的边,直到无边可消息(不阻塞进程是指申请的资源数还足够的进程)
-
死锁定理
- 若资源分配图是不可完全简化的,说明发生了死锁
-
-
-
死锁的解除
- 资源剥夺法。挂起某些死锁进程,抢占资源,将资源分配给其他死锁进程,被挂起的进程有可能会饥饿
- 撤销进程法。强制撤销部分、甚至全部死锁进程,代价很大,有可能即将完成的进程,需要从头再来
- 进程回退法。让一个或多个进程回退到足以避免死锁的地方,需要系统记录进程的历史信息,设置还原点
-
选择被处理进程考量点
- 进程优先级
- 已执行多长时间
- 还要多久能完成
- 进程已经使用多少资源
- 进程是交互式还是批处理式
8. 总结
- 重点:死锁的定义,一定是两个进程或以上才有可能造成死锁
- 重点:造成死锁的四个必要条件:互斥条件、不剥夺条件、请求和保持条件、循环等待条件
- 重点:死锁的可能发生情景,记住竞争不一定会造成死锁,同理,死锁也不是一定由竞争造成
- 重点:预防死锁的处理策略,例如预防死锁中的破坏不剥夺条件,在日常开发中,我们通常会使用到的获取锁的有限时间就是破坏不剥夺条件等,需要结合日常开发中,展开思考,日常我们预防死锁到底破坏了什么条件,加深理解。
- 重点:避免死锁,理解安全队列,银行家算法(没有详细描述,可以看去查看其他详细描述的文章)
- 请各位大佬发现错误,能指导菜鸟小弟
- 菜鸟也想努力进大厂,加油