死锁问题的相关研究
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
死锁问题的相关研究
摘要死锁是计算机操作系统学习中的一个重点,进程在使用系统资源时易产生死锁问题,若何排除、预防和避免死锁,是我们所要研究的重要问题。
关键词银行家算法;存储转发;重装死锁
所谓死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
1产生死锁的原因及其必要条件
1)产生死锁的原因。
因为系统资源不足;进程运行推进的顺序不合适;资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。
其次,进程运行推进顺序与速度不同,也可能产生死锁。
2)产生死锁的四个必要条件。
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件(占有等待):一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件(不可抢占):进程已获得的资源,在未使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
2死锁的解除与预防
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。
在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。
1)有序资源分配法。
这种算法资源按某种规则系统中的所有资源统一编号(例如打印机为1、磁带机为2、磁盘为3、等等),申请时必须以上升的次序。
采用有序资源分配法:R1的编号为1,R2的编号为2;PA:申请次序应是:R1,R2;PB:申请次序应是:R1,R2;这样就破坏了环路条件,避免了死锁的发生。
2)银行算法。
避免死锁算法中最有代表性的算法是DijkstraE.W于1968年提出的银行家算法。
该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。
这样申请者就可很快
完成其计算,然后释放它占用的资源,从而保证了系统中的所有进程都能完成,所以可避免死锁的发生。
3死锁排除的方法
撤消陷于死锁的全部进程;逐个撤消陷于死锁的进程,直到死锁不存在;从陷于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失;从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态。
死锁是网络中最容易发生的故障之一,即使在网络负荷不很重时也会发生。
死锁发生时,一组节点由于没有空闲缓冲区而元法接收和转发分组,节点之间相互等待,既不能接收分组也不能转发分组,并一直保持这一僵局,严重时甚至导致整个网络的瘫痪。
1)存储转发死锁及其防止。
最常见的死锁是发生在两个节点之间的直接存储转发死锁。
例如,A节点的所有缓冲区装满了等待输出到B节点的分组,而B 节点的所有缓冲区也全部装满了等待输出到A节点的分组;此时,A节点不能从B节点接收分组,B节点也不能从A节点接收分组,从而造成两节点间的死锁。
这种情况也可能发生在一组节点之间,例如,A节点企图向B节点发送分组、B节点企图向C节点发送分组、而C节点又企图向A节点发送分组,但此时每个节点都无空闲缓冲区用于接收分组,这种情形称做间接存储转发死锁。
当一个节点处于死锁状态时,所有与之相连的链路将被完全拥塞。
一种防止存储转发死锁的方法是,每个节点设置M+1个缓冲区,并以0到M编号。
M为通信子网的直径,即从任一源节点到任一目的节点间的最大链路段数。
每个源节点仅当其0号缓冲区空时才能接收源端系统来的分组,而此分组仅能转发给1号缓冲区空闲的相邻节点,再由该节点将分组转发给它的2号缓冲区空闲的相邻节点,最后,该分组或者顺利到达目的节点并被递交给目的端系统,或者到了某个节点编号为M的缓冲区中再也转发不下去,此时一定发生了循环,应该将该分组丢弃。
由于每个分组都是按照编号递增规则分配缓冲区,所以节点之间不会相互等待空闲缓冲区而发生死锁现象。
另一种防止存储转发死锁的方法是,使每个分组上都携带一个全局性的惟一的”时间戳”,每个节点要为每条输入链路保留一个特殊的接收缓冲区,而其它缓冲区均可用于存放中转分组。
2)重装死锁及其防止。
死锁中比较严重的情况是重装死锁。
假设发给一个端系统的报文很长,被源节点拆成若干个分组发送,目的节点要将所有具有相同编号的分组重新装配成报文递交给目的端系统,若目的节点用于重装报文的缓冲区空间有限,而且它无法知道正在接收的报文究竟被拆成多少个分组,此时,就可能发生严重的问题:为了接收更多的分组,该目的节点用完了它的缓冲空间,但它又不能将尚未拼装完整的报文递送给目的端系统,而邻节点仍在不断地向它传送分组,但它却无法接收。
这样,经过多次尝试后,邻节点就会绕道从其它途径再向该目的节点传送分组,但该目的节点已被死锁,其周边区域也由此发生了拥塞。
下面几种方法可用以避免重装死锁的发生:①允许目的节点将不完整的报文递交给目的端系统;②一个不能完整重装的报文能被检测出来,并要求发送该报文的源端系统重新传送;③为每个节点配备一个后备缓冲空间,用以暂存不完整的报文。
4操作系统死锁检测与解除相关设计
void jiesuo(int *work,int **request,int **allocation,int *finish,int *p,int m,int n) {int i,j,t,flag;
int *sum=new int[m];
for(i=0;i<m;i++) //初始化数组
sum[i]=0;
for(i=0;i<m;i++) //统计死锁资源、释放
if(p[i]==FALSE)
{ for(j=0;j<n;j++)
sum[i]=sum[i]+allocation[i][j];
allocation[i][j]=0;
}
t=sum[0];
for(i=1;i<m;i++) //找出最大死锁进程i
if(t<sum[i]) { t=sum[i];flag=i;}
cout<<”撤消占资源最大的进程:”<<flag<<endl;
for(j=0;j<n;j++) //回收资源
work[j]+=allocation[flag][j];
finish[flag]=TRUE; //完成flag进程的操作
p[flag]=FALSE; //不再对它进行判断
flag=check(work,request,allocation,finish,p,m, n); //判断是否已经解除死锁
if(flag==TRUE) {cout<<en dl; cout<<”成功解除死锁”<<endl;}。