一、死锁的产生
1、死锁的定义
所谓死锁是在多道程序中的一种现象,一组进程中的每一个进程均无限期地等待被该组进程中的另一个进程所占有且永远不会释放的资源。处于死锁状态的进程称为死锁进程。
系统发生死锁时,死锁进程的个数至少为两个;所有死锁进程都在等待资源,并且其中至少有两个进程已占有资源。
2、死锁产生的原因
死锁产生的原因主要有两个:一是竞争资源;二是多道程序运行时,进程推进顺序不合理。
(1) 资源的概念
一般把系统中的资源分成两类:一类是永久性资源(可重用资源),是指系统中可供进程重复使用、长期存在的资源;二是临时性资源(消耗性资源),是指由某个进程所产生、只为另一个进程使用一次或经过短暂时间后便不再使用的资源。
3、死锁产生的必要条件
(1) 死锁产生的四个必要条件
① 互斥条件
资源是独占的且排他使用,进程互斥使用资源。
② 不可剥夺条件
进程所获得的资源在未使用完毕之前,不能被其他进程强行剥夺。
③ 请求和保持条件
进程先申请它所需要的一部分资源,得到后再申请新的资源,在申请新资源的同时,继续占有已分配的资源。
④ 循环等待条件
又称环路等待。在发生死锁时,必然存在一个进程等待队列,形成一个进程等待环路,环路中每一个进程已占有的资源同时被另一个进程所申请。
(2) 解决死锁的四种方法
① 预防死锁
② 避免死锁
③ 检测与解除死锁
④ 忽略死锁
二、死锁的预防
1、死锁预防的概念
操作系统在系统设计时事先确定资源分配的算法,限制进程对资源的申请,从而保证不发生死锁。具体的做法是破坏产生死锁的四个必要条件之一。
2、资源的静态分配策略
(1) 破坏互斥条件
对于条件1,可以通过增加资源数量的方法来进行预防,比如提供足够多的内存,使得各个进程可以独享自己的内存空间。只不过这种死锁预防的代价比较高昂,而且有很多资源不能通过增加资源数量来解决。
(2) 破坏不可剥夺条件
① 若一个进程已经占用了某些资源,又要申请一个新的资源,在申请新资源时,不能立即得到满足,在变为等待状态之前,该进程必须释放已占有的所有资源,即阻塞前释放资源;
② 若一个进程申请某些资源,首先系统应该检查这些资源是否可用,如果可用,就分配给该进程。否则,系统检查这些资源是否分配给另外某个等待进程。如果是,系统将剥夺所需资源,分配给这个进程。如果资源没有被等待进程占有,那么该进程必须等待。在其等待过程中,其资源也有可能被剥夺。
这种方法在实现时可能会导致某个进程反复申请和释放资源,使进程执行无限推迟,增加了系统开销,延长了进程的周转时间,降低了系统的吞吐量和性能。
(3) 破坏请求和保持条件
每个进程在开始执行前就必须申请它所需要的全部资源,仅当系统能够满足进程的资源申请要求且把资源一次性分配给进程后,该进程才能开始执行。
这种方法的优点是简单、安全、容易实施;缺点是严重浪费系统资源,会造成一些资源在很长时间内得不到使用,降低资源利用率。而且还有一个问题是,大部分进程在运行开始时不能确定所需要的全部资源,那么它可以使用以下方法进行处理:
当进程没有占用资源时才允许它去申请资源,如果进程已经占用了某些资源而又要再申请资源,则它应该归还所占有的资源后再申请新的资源。
3、资源的有序分配法
它的思想是将系统中所有的资源顺序编号。一般原则为,较为紧缺、稀少的资源编号较大。进程申请资源时,必须严格按照资源编号的顺序进行,否则系统不予分配。即一个进程只有得到编号小的资源,才能申请编号较大的资源;释放资源时,应按编号递减的次序进行。
三、死锁避免
1、死锁避免的概念
死锁避免的基本思想是:系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。
死锁避免和死锁预防的区别在于:死锁预防是设法至少破坏产生死锁的四个必要条件之一,严格防止死锁的出现;而死锁避免则不是那么严格的限制产生死锁的必要条件的存在。
2、安全状态与安全序列
如果操作系统能够保证所有的进程在有限时间内得到需要的全部资源,则称系统处于安全状态,否则说系统是不安全的。
所谓安全状态是指,如果存在一个由系统中所有进程构成的安全序列,则系统处于安全状态。如果一个进程序列是安全的,那么对于其中每一个进程Pi(1 ≤ i ≤ n),,它以后所需要的资源量不会超过系统当前剩余资源量与所有进程Pj(j < i)当前占有资源量之和。
只要能使系统总是处于安全状态就可避免死锁的发生,每当有进程提出资源申请时,系统可以通过分析各个进程已占有的资源数目、还需要的资源数目以及系统中可以分配的剩余资源的数目,以决定是否为当前的申请进程分配资源。如果能使系统处于安全状态,则可为进程分配资源,否则暂不为申请进程分配资源。
3、银行家算法
银行家规定:
① 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可以接纳该顾客;
② 顾客可以分期贷款,但贷款总数不能超过最大需求量;
③ 当银行家现有的资金不能满足顾客所需要的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间内得到贷款;
④ 当顾客得到所需要的全部资金后,一定能在有限时间内归还所有的资金。
具体算法为:操作系统按银行家的规定为进程分配资源,进程首先提出对资源的最大需求量,当进程在执行中每次申请资源时,系统测试该进程已占用的资源与本次申请的资源之和是否超过了该进程对资源的最大需求量。如果超过则拒绝分配资源,若没有超过,则系统再测试现存的资源能否满足该进程所需的最大资源量,若能满足则按当前的申请量分配,否则也要推迟分配。
银行家算法示例以及伪代码实现可参考:银行家算法学习笔记
四、死锁的检测与解除
1、死锁检测的时机
检测死锁的实质是确定是否有“循环等待”条件,检测算法确定死锁的存在并识别出与死锁有关的进程和资源,以供系统采取适当的解除死锁措施。
通常,死锁检测可以在任何一次资源分配后,也可以在每次调度后,或者利用定时器定时运行检测,还有就是当系统中某个进程长期位于阻塞态或阻塞进程过多时,启动死锁检测程序。
2、死锁检测的算法
死锁检测的算法依不同的系统而不同。
3、死锁的解除方法
① 剥夺资源。经常使用的方法有:还原算法,即恢复计算结果和状态;建立检查点主要是用来恢复分配前的状态。
② 撤销进程。撤销死锁进程,将它们占有的资源分配给另外一些死锁进程,直到死锁解除为止。
五、资源分配图
1、什么是资源分配图
资源分配图是一张有向图,一个系统资源分配图SRAG可定义为一个二元组,即SRAG=(V,E),其中V是顶点的集合,而E是有向边的集合。
2、死锁定理
(1) 如果资源分配图中没有环路,则系统没有死锁;
(2) 如果资源分配图中出现了环路,则系统中可能存在死锁;
① 如果处于环路中的每个资源类中均只包含一个资源实例,则环路的存在即意味着死锁的存在。此时,环路是死锁的充分必要条件;
② 如果处于环路中的每个资源类中资源实例的个数不全为1,则环路的存在是产生死锁的必要条件而不是充分条件。
3、资源分配图化简方法
① 在资源分配图中,找出一个既非等待又非孤立的进程结点Pi,由于Pi可获得它所需要的全部资源,且运行完后释放它所占有的全部资源,故可在资源分配图中消去Pi所有的申请边和分配边,使之成为既无申请边又无分配边的孤立结点;
② 将Pi所释放的资源分配给申请它们的进程,即在资源分配图中将这些进程对资源的申请边改为分配边;
③ 重复① ② 两步骤,直到找不到符合条件的进程结点。
经过化简后,若能消去资源分配图中的所有边,使所有进程都成为孤立结点,则该图是可完全化简的;否则为不可化简的。
六、哲学家就餐问题