如何在多线程中避免发生死锁
2019-03-09 14:11
76 查看
死锁:在多道程序设计环境下,多个进程可能竞争一定数量的资源,。一个进程申请资源,如果资源不可用,那么进程进入等待状态。如果所申请的资源被其他等待进程占有,那么该等待的进程有可能无法改变状态,这种情况下称之为死锁。
死锁的四个条件:
互斥:至少有一个资源必须处在非共享模式,即一次只能有一个进程使用,如果另一进程申请该资源,那么申请进程必须延迟直到该资源释放为止。
占有并等待:一个进程必须占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有。
非抢占:资源不能被抢占
循环等待:有一组进程{P0,P1,…Pn},P0等待的资源被P1占有,P1等待的资源被P2占有,Pn-1等待的资源被Pn占有,Pn等待的资源被P0占有。
形成死锁必须要满足这四个条件。那么违背这几个条件中的任何一个就不会形成死锁,这种方式成为 死锁预防,而死锁避免是动态的检测分配资源的状态是否安全
- 死锁解决方式
- 死锁预防
- 死锁避免
- 死锁检测并恢复
三者处理死锁的方式可以类比为:死锁预防,直接铲平坑;死锁避免,直接跳过坑;死锁检测并恢复,摔到坑里,修正一下继续前行。
对于互斥而言:有的资源本身就是互斥的,所以通常无法破坏这一必要条件。
对于占有并等待:破坏它,可以指定这样的规则(协议):每一个进程执行前一次性申请完所有资源。或者 每个进程申请当前所需要的资源,当需要使用其他资源时,需要把之前申请的资源释放掉。前者可以理解为破坏等待,后者可以理解为破坏占有。这样做使得资源得利用率很低(最后阶段可能需要用一下打印机,而将其在整个运行期占有);对于优先级低得进程来说,多次释放资源很容易造成它们饥饿。
对于非抢占:破坏它,即对于已经分配的资源可以进行抢占。当一个优先级比较低,那么它的资源往往会被优先级高得剥夺,导致它饥饿。
对于循环等待:对所有资源类型进排序,要求每个进程按照资源编号递增顺序申请资源。可以用反证法证明。简要描述一下,在进程按照资源编号递增顺序申请资源的条件下,假设一个循环等待存在,即有一组进程{P0,P1,…Pn},P0等待的资源被P1占有,P1等待的资源被P2占有,Pn-1等待的资源被Pn占有,Pn等待的资源被P0占有。那么Pi+1占有了Ri资源,同时又申请Ri+1,所以资源Ri的编号必然小于Ri+1,那么R0的编号小于R1的…Rn资源的编号小于R0资源的编号(Pn进程)。根据传递性,R0的编号小于R0的编号,显然矛盾,因此,在上述条件下,不会产生循环等待。
参考:《操作系统概念》
相关文章推荐
- Java学习疑点(5)--使用多线程的时候如何注意避免死锁发生?
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁
- 一个多线程死锁案例,如何避免及解决死锁问题?
- 什么是死锁,简述死锁发生的四个必要条件,如何避免与预防死锁
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁
- 死锁发生的条件以及如何避免死锁
- java多线程如何避免死锁
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁
- 如何避免多线程中死锁?
- 死锁发生的条件,如何避免死锁
- Java多线程中如何避免死锁
- Java多线程如何避免死锁?
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁 - 虫不知
- 什么是死锁,简述死锁发生的四个必要条件,如何避免与预防死锁
- 什么是死锁,简述死锁发生的四个必要条件,如何避免死锁,解除死锁
- 多线程面试(二):在Java多线程中如何避免死锁
- 多线程之:如何避免死锁
- 数据库以及线程发生死锁的原理及必要条件,如何避免死锁。
- Linux多线程如何避免死锁