产生死锁的原因
当进程需要以独占的方式访问资源时,可能会发生死锁(Deadlock)。死锁是指两个或以上进程因竞争临界资源而造成的一种僵局,即一个进程等待一个已经被占用且永不释放的资源。若无外力作用,这些进程都无法向前推进。
产生死锁的根本原因是系统能够提供的资源个数比要求该资源的进程数要少。
产生死锁的基本原因可以分为两类:资源竞争和进程推进顺序不合理。
在资源竞争场景下,系统所拥有的资源是有限的,不能满足每个进程的需要。
例子:
A有纸,B有笔
A:你不给我笔,我就写不了作业
B:你不给我纸,我就写不了作业
彼此僵持不下……
多个程序同时运行时,进程推进顺序不合理。
例子:
A要前进2步,到桌子前,再后退2步。
但如果执行顺序不合理:A先后退,就永远到不了桌子前,触发不了后续动作,就会死锁。
产生死锁的必要条件
产生死锁的四个必要条件:
注意:这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立。反之,上述条件只要有一个不满足,就不会发生死锁。所以要避免发生死锁,只需要破坏其必要条件。
死锁的处理策略
对于死锁一般有三种处理策略:预防死锁、避免死锁、死锁的检测及解除
通过设置一些限制条件,破坏死锁的四个必要条件中的一个或几个,让死锁无法发生。
例如,将资源分层,得到上一层资源后才能够申请下一层资源,这样就破坏了环路等待条件。用户申请资源时,要求一次性申请所需要的全部资源,这就破坏了占有并等待条件。当一个已经占有某些不可剥夺资源的进程,请求新的资源而得不到满足时,它必须释放已经占有的所有资源,待以后需要时再重新申请,这就破坏了不剥夺条件。
这些预防死锁的方法破坏了系统的并行性和并发性,通常会降低系统的效率。
该方法同样属于事先预防,但它并不事先采取各种限制措施去破坏产生死锁的四个必要条件,而是在动态分配资源的过程中,用一些算法来防止系统进入不安全状态,避免死锁的发生。
具体策略如下:
1. 如果进程请求的资源会导致死锁,系统就拒绝启动该进程;
2. 如果对一个资源的分配会导致下一步的死锁,系统就拒绝本次分配;
显然要避免死锁,系统必须事先知道所拥有的资源数量及其属性。
一个著名的避免死锁的算法是银行家算法。
银行家算法是DijkstraE W于1968年提出的。之所以称为银行家算法,是因为该算法可用于银行系统。
所谓银行家算法,是指分配资源之前先确定资源分配是否会造成系统死锁。如果会死锁,则不分配,只有确认不会死锁后才进行分配。
银行家算法,需要按如下原则判断是否分配资源:
解除死锁的方法包括资源剥夺法、进程撤销法、进程回退法、系统重启法等:
剥夺陷入死锁的进程所占用的资源,但并不撤销此进程,再将这些资源分配给需要的进程,直至死锁解除。
让所有的进程回退到系统保存的检查点,这种方法要求系统建立并保存检查点、建立回退机制。