1. 死锁问题的情景
例如:系统中只有一台扫描仪R1和一台刻录机R2.有两个进程P1和P2,他们都准备将扫描的文档刻录到光盘上,进程P1先请求扫描仪并获得成功,进程P2先请求刻录机并获得成功。后来P1又请求刻录机,因为刻录机被分配给了了P2而导致阻塞;P2又请求扫描仪,因为扫描仪被分配给了P1而导致阻塞。双方都希望对方能释放资源而成全自己,但是双方都不让步,然后就一直僵持下去。
再例如哲学家进餐问题也是死锁的问题场景。
2. 死锁产生的四个必要条件
只要其中任意一个不成立,则死锁就不会发生。
(1)互斥条件;即在一段时间内,一个资源只能被一个进程占用。
(2)请求和保持条件;进程已经获得了某种资源,但又提出了新的资源的要求,而该资源已经被其他进程占有,此时请求进程被阻塞,但对自己保持的资源不放。
(3)不可抢占资源;进程已获得的资源在未使用完成之前不能被其他进程抢占。
(4)循环等待条件;在发生死锁时,必然存在一个循环链。
3. 处理死锁的方法
(1)预防死锁
去破坏产生死锁的四个必要条件中的一个或几个来预防死锁的产生。
(2)避免死锁
在资源的动态分配过程中,用某种方法防止系统进入不安全状态,避免死锁的发生。
(3)检测死锁
通过检测机构检测出死锁的发生,然后采取适当的措施。
(4) 解除死锁
当检测到死锁已经发生时,撤销一些进程,回收他们的资源,将他们分配给其他需要的进程,使其继续运行。
4. 预防死锁
由于互斥条件是保护临界资源的一种措施,所以不仅不能改变,还要加以保证。所以只能破坏其他三个条件。
(1)破坏“请求和保持条件”
第一种协议:进程必须一次性的申请所需的所有资源,并且系统有足够的资源分配给他,否则就不分配。
这种协议的优点是简单,易行且安全,但存在很大的问题,比如资源严重浪费和是进程发生饥饿现象。
第二种协议:允许一个进程只获得运行初期的所需资源,在进程运行过程中,将运行完成的资源释放,然后再请求其他所需资源。
(2)破坏“不可抢占条件”
将不可抢占变成可抢占的资源,实现起来较为复杂,且需要付出很大的代价。
(3)破坏“循环条件”
将循环条件改为层次分配策略
5. 避免死锁
在资源的动态分配过程中,防止系统进入不安全状态,以避免发生死锁。
安全状态:只要存在一种可以顺利完成任务的顺序就属于安全状态。
不安全状态:没有任意一种顺序使任务顺利完成。
利用银行家算法避免死锁
银行家算法是Dijkstra提出的,该算法最初是为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需求的情况。
为实现银行家算法,每一个新进程在进入系统时,必须申明在运行过程中,可能需要的资源的最大单元数目,其数目不应该超过系统资源总量。
(1) 银行家算法中的数据结构
系统中设置了四个数据结构,分别是系统中可利用的资源,所有进程对资源的最大需求,系统中的资源分配,所有进程还需资源的数目。
1)可利用资源向量Available。这是一个含有m个元素的数组,他表示了系统中可利用的每种资源的数目;如果Available[j]=K,则表示系统中现有Rj个资源K个。
2)最大需求矩阵Max。这是一个n*m的矩阵,表示了系统中的进程对某类资源的最大需求;如果Max[i,j]=K,则表示进程i需要的Rj类资源的最大数目为K个。
3)分配矩阵Allocation。这是一个n* m的矩阵,表示了系统中每一类资源分配给每一进程的资源数;如果Allocation[i,j]=K,则表示该进程i已经获得Rj资源的数目为K个。
4)需求矩阵Need。这也是一个n*m的矩阵,表示每一个进程需要的各类资源数;如果Need[i,j]=K,则表示该进程i 还需要Rj资源的数目为K个。
上述三个矩阵存在如下关系:
Need[ i, j ]=Max[ i, j ]- Allocation[ i, j ]
(2). 银行家算法
设Request i 是进程Pi的请求向量,如果Requesti[ j ]=K,表示进程 Pi 需要 K 个 Rj 类型的资源,当Pi发出请求时,系统按照如下步骤进行检查:
(1)如果Requesti [ j ]<= Need[ i ][ j ],则转(2);否则,认为它所需要的资源超过它所申请的最大值;
(2)如果Requesti [ j ]<= Avaliable[ j ],则转(3);否则,表示系统中的资源不满足需求。
(3)系统试探分配资源,修改相关数据:
Avaliable [ j ]-=Request[ i ][ j ] ;
Allocation[ i ][ j ]+=Requeat[ i ][ j ];
Need[ i ][ j ]-=Request[ i ][ j ];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
6. 死锁的解除
解除死锁的方法:
(1)抢占资源。从一个或多个进程中抢占足够数量的资源,分配给死锁进程。
(2)终止进程。终止系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态解脱出来。
在系统中造成死锁的原因很多,并且死锁是一个麻烦的问题,我们要通过这些方法解决死锁问题。