产生死锁的条件和解决死锁的方法

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)终止进程。终止系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态解脱出来。

在系统中造成死锁的原因很多,并且死锁是一个麻烦的问题,我们要通过这些方法解决死锁问题。

 

 

 

 

你可能感兴趣的:(Linux)