一、死锁的定义
多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
二、死锁产生的原因
1)竞争不可抢占性资源
p1已经打开F1,想去打开F2,p2已经打开F2,想去打开F1,但是F1和F2都是不可抢占的,这是发生死锁。
2)竞争可消耗资源引起死锁
进程间通信,如果顺序不当,会产生死锁,比如p1发消息m1给p2,p1接收p3的消息m3,p2接收p1的m1,发m2给p3,p3,以此类推,如果进程之间是先发信息的那么可以完成通信,但是如果是先接收信息就会产生死锁。
3)进程推进顺序不当
进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁。
死锁产生的必要条件
产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。
- 互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
- 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
- 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
- 循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, ..., pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, ..., n-1),Pn等待的资源被P0占有,
三、避免死锁的方法
1)破坏“请求和保持”条件
想办法,让进程不要那么贪心,自己已经有了资源就不要去竞争那些不可抢占的资源。比如,让进程在申请资源时,一次性申请所有需要用到的资源,不要一次一次来申请,当申请的资源有一些没空,那就让线程等待。不过这个方法比较浪费资源,进程可能经常处于饥饿状态。还有一种方法是,要求进程在申请资源前,要释放自己拥有的资源。
2)破坏“不可抢占”条件
允许进程进行抢占,方法一:如果去抢资源,被拒绝,就释放自己的资源。方法二:操作系统允许抢,只要你优先级大,可以抢到。
3)破坏“循环等待”条件
将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出
四、死锁解决方法
在有些情况下死锁是可以避免的。以下是避免死锁的技术:
- 加锁顺序(线程按照一定的顺序加锁)
- 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
- 死锁检测
步骤一:每个进程、每个资源制定唯一编号
步骤二:设定一张资源分配表,记录各进程与占用资源之间的关系
步骤三:设置一张进程等待表,记录各进程与要申请资源之间的关系 资
资源 | 进程 |
---|---|
r1 | p2 |
r2 | p5 |
r3 | p4 |
r4 | p1 |
资源 | 进程 |
---|---|
p1 | r1 |
p2 | r3 |
p4 | r4 |
p1-r1-p2-r3-p4-r4-p1 出现环路引起死锁
- 银行家算法
例如:如果有五个进程P1,P2,P3,P4,P5,三类资源A,B,C,各类资源的数量分贝为10、5、7,在T0时刻的资源分配如下:
T0时刻的安全性:利用安全性算法对T0时刻进行分析,在T0时刻存在一个安全序列P1,P3,P4,P2,P0,所以系统是安全的。