死锁的产生、解除与预防
2012-10-03 19:13
155 查看
死锁是指两个或两个以上的进程在执行的过程中,因争夺资源而造成的一种互相等待的现象。
产生死锁的四个必要条件:
1、互斥条件:一个资源每次只能被一个进程使用。
2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(资源的部分分配)
3、不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
上述四个条件是产生死锁的四个必要条件,只要上述四个之中有一个不满足,就不会发生死锁。
根据上述条件,列出三条预防措施:
1、采用资源静态分配的策略,破坏“部分分配”条件。
2、允许进程剥夺使用其他进程占有的资源,从而破坏“不可剥夺”条件。
3、采用资源有序分配方法,破坏“环路”条件。
注意:互斥条件没法被破坏。
死锁避免算法里最著名的算法就是Dijkstra的银行家算法。
银行家算法:
基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
安全性检查算法:
(1)设置两个工作向量Work=AVAILABLE; FINISH(全为false)
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work+=ALLOCATION;
Finish=true;
GOTO(2)
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。
银行家算法的代码实例:
产生死锁的四个必要条件:
1、互斥条件:一个资源每次只能被一个进程使用。
2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(资源的部分分配)
3、不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
上述四个条件是产生死锁的四个必要条件,只要上述四个之中有一个不满足,就不会发生死锁。
根据上述条件,列出三条预防措施:
1、采用资源静态分配的策略,破坏“部分分配”条件。
2、允许进程剥夺使用其他进程占有的资源,从而破坏“不可剥夺”条件。
3、采用资源有序分配方法,破坏“环路”条件。
注意:互斥条件没法被破坏。
死锁避免算法里最著名的算法就是Dijkstra的银行家算法。
银行家算法:
基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
安全性检查算法:
(1)设置两个工作向量Work=AVAILABLE; FINISH(全为false)
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work+=ALLOCATION;
Finish=true;
GOTO(2)
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。
银行家算法的代码实例:
#include<stdio.h> #include<stdlib.h> #include<string.h> #define N 5 //进程个数 #define M 3 //资源种类 int main() { int i,j; int a; int Request[M];//请求资源距阵 int Allocation [M];//已经分配资源矩阵 int Need [M];//需求矩阵 int Available[M];//可利用资源量 //输入已经分配的资源 printf("请输入已经分配的资源:\n"); for(i=0;i<N;i++) { printf("请输入第 %d 个进程已经分配的资源:",i+1); for(j=0;j<M;j++) scanf("%d",&Allocation[i][j]); } //输入各个进程还需要的资源 printf("\n请输入各个进程还需要的资源:\n"); for(i=0;i<N;i++) { printf("请输入第 %d 个进程还需要的资源:",i+1); for(j=0;j<M;j++) scanf("%d",&Need[i][j]); } //输入可以利用的资源数据 printf("\n请输入可以利用的资源数据:"); for(i=0;i<M;i++) scanf("%d",&Available[i]); while(1) { start:printf("\n\n请输入是第几个进程发出资源请求:"); scanf("%d",&a);//输入的是第几个进程的请求 printf("\n第 %d 个进程资源请求数:",a); for(i=0;i<M;i++) scanf("%d",&Request[i]); //银行家算法第一步 for(i=0;i<M;i++) { if(!(Request[i]<=Need[a-1][i])) { printf("P%d 非法请求!",a); printf("不可以分配给 P%d 进程!",a); goto start; } } //银行家算法第二步 for(i=0;i<M;i++) { if(!(Request[i]<=Available[i])) { printf("P%d 进程阻塞!",a); printf("不可以分配给 P%d 进程!",a); goto start; } } //银行家算法第三步:试探性分配 for(i=0;i<M;i++) { Available[i]=Available[i]-Request[i]; Allocation[a-1][i]=Allocation[a-1][i]+Request[i]; Need[a-1][i]=Need[a-1][i]-Request[i]; } //银行家算法第四步:安全性检查 int Finish ={0,0,0,0,0}; int Work[M]; for(i=0;i<M;i++) Work[i]=Available[i]; int flag=1; while(flag==1) { for(i=0;i<N;i++) { for(j=0;j<M;j++) { if(Finish[i]==0 && Need[i][j]<=Work[j]) { if(j==M-1) { Finish[i]=1; printf("\nP%d 进程安全性检查通过",i+1); for(j=0;j<M;j++) Work[j]=Work[j]+Allocation[i][j]; } } continue; } } int sum=0; for(i=0;i<N;i++) sum=sum+Finish[i]; if(sum==5) flag=0; } for(i=0;i<N;i++) { if(Finish[i]==0) { printf("试探性分配不成功!安全性检查不通过!"); printf("\n不可以分配给 P%d 进程!",a); Available[i]=Available[i]+Request[i]; Allocation[a-1][i]=Allocation[a-1][i]-Request[i]; Need[a-1][i]=Need[a-1][i]+Request[i]; goto start; } } printf("\n\n安全!可以分配给 P%d 进程!\n",a); //输出分配成功后资源占有、需求和可利用情况 printf("\n资源占有情况:\n"); for(i=0;i<N;i++) { printf("P%d 个进程已经分配的资源:",i+1); for(j=0;j<M;j++) printf(" %d ",Allocation[i][j]); printf("\n"); } printf("\n资源需求情况:\n"); for(i=0;i<N;i++) { printf("P%d 个进程还需要的资源:",i+1); for(j=0;j<M;j++) printf(" %d ",Need[i][j]); printf("\n"); } printf("\n可以利用的资源数据:"); for(i=0;i<M;i++) printf(" %d ",Available[i]); printf("\n"); } return 0; }
相关文章推荐
- 牛客网Java刷题知识点之什么是死锁、死锁产生的4个必要条件、死锁的解除与预防
- Linux_进程死锁?产生条件?产生原因?怎样预防?怎样检测死锁和解除死锁?
- 死锁产生的原因和必要条件及预防死锁的方法及死锁的检测与解除
- 死锁产生的必要条件及其预防和解除
- 死锁产生的原因和必要条件及预防死锁的方法及死锁的检测与解除
- 死锁产生的原因和必要条件及预防死锁的方法及死锁的检测与解除
- 死锁的产生、预防、以及接触方法整理,一目了然
- 死锁的理解---产生条件、避免方法、死锁解除
- 死锁产生和预防
- 死锁的产生和预防死锁
- 死锁的产生与预防
- 操作系统学习-14 预防死锁与死锁解除
- 关于死锁的预防,产生,解决的方法
- 死锁四个必要条件及死锁的预防、检测、避免、解除
- 死锁的定义、产生原因、必要条件、避免死锁和解除死锁的方法
- 死锁及解除和预防方法
- 死锁的产生、预防和避免
- 死锁(deadlocks)及其预防和解除方法
- 死锁的产生原因和解除
- 死锁的产生、预防和避免