面试题:什么是死锁?死锁必要条件是?死锁如何产生及如何预防?
这是面试题库里面的一道京东、字节、腾讯的面试题。针对这一面试题,在这里我来谈谈我自己的理解。
什么是死锁?
如果某一进程所申请的资源被其他正在等待资源的进程所占有,那么该进程可能一直处于等待资源的状态。(简单来说,对于两个进程而言,就是一个进程A申请的资源被进程B所占有,而进程B也在申请资源,恰好这部分资源被进程A所占有,这就构成了死锁。对于多个进程而言,死锁就是多个进程互相占有资源而又向对方申请资源,从而构成一个闭环。)
死锁的四个必要条件
满足了这四个条件的进程不一定死锁,但死锁的进程必定满足这四个条件。
1.互斥
某一资源一次只可给一个进程使用,即同一个资源不可共享使用。
2.占有且等待
一个进程占有部分资源,又在等待另一部分资源(而等待的资源又被其他进程所占有)。
3.非抢占
除非进程主动释放资源,否则进程占有的资源不能够被其他进程抢占。
4.循环等待
P0所需资源被P1占有,P1所需资源被P2所占有......Pn-1所需资源被Pn占有Pn所需资源又被P0占有
处理死锁的方法
- 死锁预防或死锁避免(这种情况下,系统不会进入死锁状态)
- 允许系统进入死锁状态,一旦检测到进入了死锁状态,那么恢复为未死锁状态(这种情况下,系统会进入死锁状态)
- 忽视这一问题,默认死锁不会发生(这是目前大多数系统所采用的方法)
方法一对于处理死锁问题是比较有效的,下面我们来仔细谈谈死锁预防和死锁避免的实现机制。
死锁预防
通过令四个必要条件中的一个不成立,从而达到预防死锁的目的。不同的必要条件对应一个不同的预防方法。
- 1)针对互斥:令资源为共享资源。(缺点:共享容易产生混乱)
- 2)针对占有且等待:保证当一个进程申请一个资源时,他不能占有其他资源。即要么进程一下子获得所有所需资源,要么不占有任何资源。
- 3)针对非抢占:如果一个进程正在申请不能被立即分配的资源,即正在等待分配,那么该进程已占有的资源可被其他资源抢占。
- 4)针对循环等待:对所有资源类型进行排序,每个进程按资源递增顺序申请资源,系统按序分配资源。
死锁避免
每当遇到资源分配请求时,首先假设这样分配,如果这样分配完后系统仍处于安全状态,那么就满足该请求;否则让该请求等待。
在这里,我们首先需要了解什么是安全状态和安全序列。 安全序列:进程序列<P1,P2,P3......Pn>,如果对每个Pi(代表一个进程),都有
,则该序列是安全序列。因为在这种情况下,即使进程Pi需要的资源不能立即可用,但他可以等前面的所有进程Pj运行完后释放资源。
安全状态:如果存在一个安全序列,那么系统处于安全状态。
( 并非所有的非安全状态都能导致死锁状态)
死锁避免的两个算法:资源分配图算法和银行家算法
资源分配图算法
在资源分配图的基础上新增一类从进程指向资源的边,称为需求边(当前不用该资源,但以后要用),用虚线表示。如果将某一虚线变成实线进行分配后,即将需求边变为分配边后,如果没有产生环,则说明系统处于安全状态,不会产生死锁。
银行家算法
每次请求到来时,都首先用资源请求算法模拟满足该请求,然后利用安全算法判断这样分配后系统是否处于安全状态。如果系统处于安全状态,则真正满足该请求;否则让该请求等待,再去模拟满足另一请求。
在这两种算法里面,用的最多的是银行家算法。我们也常用银行家算法里面的安全算法来判断是否存在死锁。 这是对于解决死锁问题方法一的介绍,在这种情况下系统可以保证不会进入死锁状态。如果利用方法二解决死锁问题,那么系统可能处于死锁状态,我们还需要考虑当系统处于死锁状态时如何将系统恢复为未死锁的状态(也称死锁的恢复),在这里便不再细讲,有兴趣的伙伴可以自行查找一下相关资料。实际上,大多数系统处理死锁问题采取的都是方法三,即默认死锁不存在。这是因为当系统资源足够时,死锁的发生概率是很低的,而且无论是死锁预防还是死锁避免,都或多或少对系统的正常运行造成了影响(死锁预防的四个方法都有着各自的缺点,死锁避免实现的时间复杂度太大)。这也是为什么我们偶尔会出现电脑卡死没有响应的情况,在这种情况下,我们只好按下电源键重启电脑来解决死锁问题。