进程死锁

来源:互联网 发布:开源网络代理服务器 编辑:程序博客网 时间:2024/06/06 04:14


进程死锁:(deadlock)
(一)死锁的定义:
(1)背景:
在多道程序系统中,同时有多个进程并发运行,共享系统资源,从而提高了系统资源利用率,提高了系统的处理能力。但是,若对资源的管理、分配和使用不当,则会产生死锁或是饥饿。

(2)死锁定义:
几个进程请求资源发生环路,导致无法向前推进,永久阻塞的情况。

(二)死锁的原因:
(1)资源不足:
(2)进程推荐顺序不合理:

(三)死锁与饥饿(starvation)的区别:

(1)饥饿的定义:
饥饿:一个进程长时间得不到需要的资源而不能执行的现象。
(2)饥饿举例:
当有多个进程需要打印文件时,如果系统分配打印机的策略是最短文件优先,那么长文件的打印任务将由于短文件的源源不断到来而被无限期推迟,导致最终的饥饿甚至饿死。
(3)避免饥饿:
饥饿和饿死与资源分配策略有关,避免饿死就应该是采用队列的方式,保证每个人都有机会获得请求的资源。当然实现方式可以很多个变化,比如优先级,时间片,等,都是“队列”的特殊形式。

(2)死锁与饥饿的区别:
1.进程状态:
死锁的进程都是等待进程,但是饥饿进程可能处于就绪状态。
2.死锁进程至少是两个进程,一定存在循环等待;
但是饥饿进程可能是一个进程,不一定存在循环。
3.死锁进程等待的是永远不会被释放的资源,而饥饿进程等待会被释放但不会分配给自己的资源。


(三-1)死锁的特点:
(1)参与死锁的进程至少有2个;
(2)每个参与死锁的进程均在等待资源,处于阻塞状态;
(3)参与死锁的进程至少有2个进程占有了资源;
(4)死锁的进程是当前进程集合的一个子集;

(四)死锁的四个必要条件:
(1)互斥:
一个资源在同一时刻只能分配给一个进程;
(2)不可抢占:
任何一个进程不可以从另一个进程处抢夺资源,即:资源只能由进程自己来释放。
(3)请求和占有:
一个进程请求资源得不到满足而等待时,不释放已经占有的资源。
(4)循环等待:
存在一个循环等待链,环中的每一个进程分别等待前一个进程所占有的资源,而造成永久等待。

(五)死锁的预防:
死锁的预防是根据死锁的四个必要条件来提出的:
(1)互斥:
破坏方法:很难实现破坏互斥。
(2)不可抢占:
破坏方法:一个进程请求被另一个进程占有的资源时,操作系统允许抢占。
(3)请求并占有:
破坏方法:
占有某些资源的一个进程 进一步申请其他资源被拒绝时,则该进程释放它占有的资源。
(4)循环等待:
破坏方法:
所有的进程按照类型赋予一个编号,(如:打印机为1,磁带机为2),要求每一个进程均严格按照 编号递增的顺序来申请资源。
即:只要进程提出申请资源Ri,则在该进程以后的资源申请中,只能申请资源编号排在Ri后面的那些资源,不能再申请编号低于Ri的资源。

(六-1)判断进程是否死锁:
资源分配图见下图:



(六)死锁的避免之银行家算法:
(1)定义:
1.安全状态:按照某种策略为系统中的每个进程分配资源,使得所有进程可以按照某种顺序全部执行,则成为安全状态。

(六-2)银行家算法:
n个进程(p1,p2...pn),m类资源(R1,R2..Rm)

(1)数据结构:
1.Available : array[1...m] of int
Available[i]=k表示有Ri类资源k个。

2. Max: array[1...n,1...m] of int
Max[i,j]=k表示进程Pi最多需要资源Rj k个。

3.Allocation: array[1...n,1...m] of int。
Allocation[i,j]=k表示进程Pi已经获得Rj类资源k个,
Allocation[i]:array[1...m]表示进程Pi的分配向量,为二维数组Allocation的第i行。

4.Need: array[1...n,1...m] of int;
Need[i,j]=k,表示进程Pi还需要Rj类资源为k个。
Need[i]:array[1...m];表示进程Pi所需的进程数组。

5.Request:array[1...n,1...m] of int;
Request[i,j]=k,表示进程Pi请求Rj类资源k个。
Request[i]表示进程Pi的请求表。

安全性检查:
6. Finish[1...n] of  boolean;
Finish[i]=true/false,表示进程i是否执行完。

7. Work: array[1...m] of int;
Work[i]表示资源Ri可使用个数。初始时,Work=Available;
也可以直接省略Work,在安全性检查时,继续使用Available数组。

(2)资源分配表:(预分配)
1.如果Request[i]<=Need[i] 则执行2,否则出错;
2.如果Request[i]<=Available[i],则执行3,否则资源不足,Pi等待。
3.对进程pi进行资源的预分配:
Avaiable=Available-Request[i];
Need[i]=Need[i]-Request[i];
Allocation[i]=Allocation[i]+Request[i];

(3)安全性检查:(真实分配)

1)安全性定义:
预分配后,需要进行安全性检查,所谓安全性检查,即给进程Pi分配了资源后,所有的进程能否按照某种顺序全部执行。如果都可以执行,安全;否则不安全。
2)Finish:
Finish[i]=true,表示进程Pi可以完成,Finish[i]=false,表示进程Pi不能完成。
开始时,所有的Finish[i]=false,当执行完毕,则Finish[i]=true;

3)安全性检查的步骤:

1.如果Finish[i]=fasle,且Available<=Need[i],则执行i。

2.Finish[i]=true;
Available=Available+Allocation[i];转到步骤1;

3.对于所有的Finish[i]=true;则处于安全状态,否则不安全。



1 0
原创粉丝点击