简述
死锁是指两个或两个以上的进程在执行过程中,由于资源抢占或者相互通信而造成的一种阻塞现象。
死锁产生的必要条件
- 互斥条件:进程分配到的资源具有排他性,同一段时间内只能由一个进程使用,如果此时还有别的进程请求该资源,则请求者等待,直到占有资源的进程释放资源。
- 请求保持条件:当前进程已经拥有至少一个资源,又请求新的资源,而请求资源已经被别的进程占用了,此时当前进程阻塞,而且手中拥有的资源也不释放。
- 不剥夺条件:进程已经拥有的资源,没有使用完成之前,不能被剥夺,只能自己使用完释放掉。
- 循环等待条件:资源循环链,A占用了B要用的资源,B等待;B也占用了A的资源,A等待。
搭配画图解释一下
- 两辆救护车分别拉病人赶往医院,假设为进程A、进程B;
- 道路为进程所需要的资源;
- 互斥:道路变窄(资源减少)本来能并行的,只能单行了。
- 请求保持:都已经开进窄路一部分了,开不进去也不退出来,就堵这;进程A、进程B都获得了一部分资源,但是不够,需要继续请求更多的资源。
- 不剥夺:A、B开进来一部分了,不走完,占用的道路就一直占用。
- 循环等待:A等B释放资源,好独享道路走掉,B等A释放资源,好独享道路走掉。
感觉描述还是不够清楚,其实在这里我脑海里一直有这样一个画面,上图:
解决方案
出现问题就解决问题,有死锁就肯定有针对死锁的解决方案,从必要条件上出发其实有这么几个方向考虑:
- 资源互斥是根本,一般来说不动。
- 请求保持,那就干掉请求。
- 全部请求干掉。
- 一个一个请求干掉,直到死锁不存在。
- 不剥夺,强制剥夺。
- 所有陷入死锁的进程都把资源剥夺掉。
- 逐个剥夺陷入死锁的进程的资源,直到死锁不存在。
- 循环等待,A等B,B等C,C等A。强制剥夺一个资源给其他进程。
解决方案plus
死锁出现了再解决问题,都是干掉、剥夺,破坏性的解决,那能不能提前预防死锁的出现呢?其实可以的。
- 死锁预防
- 预先设置一些限制条件,破坏产生死锁的四个必要条件中一条或几条,一般预先设置的限制条件都比较严格,会导致系统资源利用率和系统吞吐量降低。
- 死锁避免
- 针对进程的资源申请以及现有的资源进行动态检查,再根据检查结果决定是否分配资源。
常见的两种避免死锁的方法:
有序资源分配法
对某种规则下的资源统一编号,原则:
- 进程使用的同一类的所有资源,必须一次申请完。
- 进程申请不同类型资源时候,按照编号依次申请。
其实就是,资源在这个时间点你用,在下个时间点我用,时间上彼此衔接互不冲突。
银行家算法
据说这个很有名,不过没怎么用过,我的理解有以下几个特征:
- 当前拥有的资源,满足进程的最大申请量,允许申请。
- 进程可以分批申请资源,但是申请的总额度,不能超过最大值。
- 进程申请资源,当资源不足时,可以在有限时间内补足资源。
- 进程申请资源后,必须在一定时间内归还资源。