来看看死锁是个撒玩意儿
区分死锁、饥饿、死循环
死锁:各进程中拿着对方所需的资源,你瞪我,我瞪你,导致各个进程都无法推进
饥饿:某个进程的资源一直被其他进程给占用,就如被命运掐住了喉咙。列入短进程优先策略,资源一直被短进程给占用,导致较长的进程一直获取不到资源
死循环:某个进程一直跳不出某个循环,有可能是BUG,也有可能程序员自个儿设置的
产生死锁的条件
必须满足以下4个条件:
- 互斥条件
互斥的争夺资源才会导致死锁(哲学家、打印机设别) - 不剥夺条件
只能由自个儿的进程释放资源,不能由其他进程强行抢夺 - 请求和保持条件
进程手中至少掌握一个资源,去获取需要的资源时又被其他进程给占有,自己掌握的资源又不释放 - 循环等待条件
形成一个进程资源的循环等待链,自个进程拥有的资源又是被下个进程请求
啥时候会发生死锁
- 对系统资源的竞争
各进程对不可剥夺的资源的竞争可能会引起死锁 - 进程推进的顺序不合理
进程p1,p2分别占有了r1,r2。紧接着p1,p2又想请求r2,r1。可是这两个资源都给占有了,你不让,我不让你,就一直僵持下去 - 信号量使用不当
在生产者-消费者问题中,实现互斥在实现同步之气,就可能导致死锁
解决策略
1. 预防死锁
- 破坏互斥条件(不推荐)
SPOOLing技术、进程与资源之间加上一个输出进程。
缺点:但是大多数系统需要互斥的存在 - 不剥夺条件(可能会导致一段工作失效)
当进程所需资源时,直接释放被占有的资源。
缺点:若一直重新释放资源,资源又需要重新申请,可能会导致饥饿 - 破坏请求和保持条件
采用静态分配方法,一次性申请所有所需的资源。不满足资源条件,不投入运行。
缺点:造成资源浪费,资源利用率低,可能会导致饥饿 - 破坏循环等待条件
采用顺序资源分配法,给每个系统资源编号
缺点:必须按照递增的顺序请求资源,只能拥有小编号资源时,才能申请大编号的资源。
2. 避免死锁
安全序列:按照某种序列分配资源,每个进程都能顺利完成
不安全状态:系统中找不出任何一个安全序列
解决方案:银行家算法
核心思想:
- 申明available、request三元组分别做可获得资源和需求资源,每个进程用一个三个三元组来表示,分别是最大需求、已分配、最多还需要,每一个三元组分别表示资源的数量
步骤:
- 检查此次申请资源数量是否超过 最大需求的资源数量
- 检查此时系统剩余的可用资源 是否瞒住 这次请求
- 试探着分配,更改各数据结构
- 用安全性算法检查此次分配是否导致系统进入不安全状态
3. 死锁的检测和解除
死锁的检测,使用图的方式,建立联系
结点用作表示进程和资源
边用于表示 进程与资源的请求关系
通俗解释:依次消除 资源足够的进程的边,知道无边可以消除
- 两种结点
进程结点
资源结点 - 两种边
进程结点
资源结点
解除:
- 资源剥夺法
- 撤销进程法
- 进程回退法