死锁产生的条件及解决
死锁产生的条件
- 互斥
线程对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个线程所占有。
此时若有其他线程请求该资源,则请求线程只能阻塞等待。
- 不可剥夺
线程所获得的资源在未使用完毕之前,不能被其他线程强行夺走,即只能由获得该资源的线程自己来释放。
请求与保持
线程在至少拥有一个资源的情况下,线程继续请求其它资源,而该资源被其他线程所持有,
此时线程被堵塞,但保持对现有资源的持有。循环等待
存在线程资源的循环等待链,链中每一个线程已获得的资源同时被下一个线程所请求。
即A等待B,B等待C,C等待A。
只有同时满足以上四个条件才有可能发生死锁,只要有一个不满足就不会发生。
预防死锁
破坏互斥
不好意思,破坏不了。。
互斥条件不能被破坏,否则会造成结果的不可再现性 即 原子性问题
破坏不可剥夺
如果占有某些资源的一个线程进行进一步资源请求被拒绝,则该线程必须释放它最初占有的资源。
如果一个线程请求当前被另一个线程占有的一个资源,则可以抢占另一个线程,要求它释放资源。 剥夺资源法
破坏请求与保持
1,创建线程时,要求它申请所需的全部资源,系统要么满足其所有要求,要么什么也不给它。即 一次性分配策略
2,要求每个线程提出新的资源申请前,释放它所占有的资源。
破坏循环等待
资源有序分配法,即所申请的资源必须按照顺序申请。
避免死锁
预防死锁和避免死锁的区别:
预防死锁是设法至少破坏产生死锁的四个必要条件之一,严格的防止死锁的出现,而避免死锁则不那么严格的限制产生死锁的必要条件的存在,因为即使死锁的必要条件存在,也不一定发生死锁。避免死锁是在系统运行过程中注意避免死锁的最终发生。
资源有序分配法
对它所必须的资源,必须一次申请完。
所申请的资源必须按照顺序申请。
即线程A申请A资源,B资源,C资源,B线程也得A资源,B资源,C资源。避免可能有生成环路的条件。
银行家算法
银行家算法
加锁顺序
当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。
如果能确保所有的线程都是按照相同的顺序获得锁(类似资源有序分配法),那么死锁就不会发生。
加锁时限
线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁。然后等待一段随机的时间再重试
死锁检测
死锁定理:
如果资源分配图中没有环路,则系统中没有死锁,如果图中存在环路则系统中可能存在死锁。
如果每个资源类中只包含一个资源实例,则环路是死锁存在的充分必要条件。
找一个非孤立、只有分配边的线程结点,去掉分配边,将其变为孤立结点;
再把相应的资源分配给一个等待该资源的线程,即将某线程的申请边变为分配边;
重复以上步骤,若所有线程都可成为孤立结点,称该图是可完全简化的,否则称该图是不可完全简化的。
死锁状态的充分条件是:资源分配图是不可完全简化的。
死锁:
无死锁:
解除死锁
资源剥夺法。挂起某些死锁线程,并抢占它的资源,将这些资源分配给其他的死锁线程。
但应防止被挂起的线程长时间得不到资源,而处于资源匮乏的状态。撤销线程法。强制撤销部分、甚至全部死锁线程并剥夺这些线程的资源。
撤销的原则可以按线程优先级和撤销线程代价的高低进行。线程回退法。让一(或多)个线程回退足以回避死锁的地步,线程回退时自愿释放资源而不是被剥夺。
要求系统保持线程的历史信息,设置还原点。