二死锁的检测与解除.docx
《二死锁的检测与解除.docx》由会员分享,可在线阅读,更多相关《二死锁的检测与解除.docx(11页珍藏版)》请在冰豆网上搜索。
![二死锁的检测与解除.docx](https://file1.bdocx.com/fileroot1/2022-11/23/3a997dbc-cb35-4bbd-99d8-cf9f7415a9d0/3a997dbc-cb35-4bbd-99d8-cf9f7415a9d01.gif)
二死锁的检测与解除
实验二死锁的检测与解除
一、实验目的:
当系统为进程分配资源时,若未采取任何限制性措施,则系统必须提供检测和解除死锁的手段,为此,系统必须做到:
(1)保存有关资源的请求和分配信息;
(2)提供一种算法,以利用这些信息来检测系统是否已进入死锁状态。
某一状态为死锁状态的充分条件是:
当且仅当某一状态的资源分配图是不可完全简化的。
通过该实验,可以充分理解死锁的检测与解除的基本原理。
二、实验题目:
设计一个m 个并发进程共享n个系统资源的系统。
进程可动态申请资源和释放资源,系统按各进程的申请动态的分配资源。
要求用死锁检测算法检测当某一进程提出资源分配请求时,系统会不会陷入死锁状态;如若陷入死锁状态要求用某种算法解除死锁
三.实验源程序文件名:
sisuo.cpp
执行文件名:
sisuo.exe
四、实验分析
1)本实验采用死锁检测算法检测死锁,死锁检测的数据结构如下
(1)可利用资源向量available,它表示了n类资源中每一类资源的可用数目。
(2)把不占用资源的进程用finish[i]=true标示
(3)从进程集合中找到一个request[i]<=work的进程,做如下处理:
将其资源分配图简化,释放出资源,增加工作向量work:
=work+allocation[i],并将其finish[i]置1
(4)若不能把所有的进程都标记为finish[i]==1,则表明该系统状态将发生死锁
当发现进程死锁时,便应立即把它们从死锁状态中解脱出来。
本实验采用的解除死锁的方法是:
撤销进程。
本实验采用撤销的进程数目最小的方法,把死锁进程中占有资源最多的进程撤销,如若仍发生死锁,继续撤销下一进程
2)流程图:
(1)主函数流程图
(2)judge函数流程图
(3)check函数流程图
(4)解锁函数流程图
3)源代码
#include
#include
#include
usingnamespacestd;//名字空间
#defineTRUE1
#defineFALSE0//布尔值
intcompare(int**request,int*work,intN,intk)//如果Request[i]>work则返回false
{
intj,c=0;
for(j=0;j{
if(request[k][j]>work[j])
{c++;}
}
if(c>0)returnFALSE;
elseif(c==0)returnTRUE;
}
//判断
intcheck(int*work,int**request,int**allocation,int*finish,int*p,intm,intn)
{
inti,j,flag=TRUE,K=0;
while(flag==TRUE)//反复判断,直到无法判断
{
flag=FALSE;
for(i=0;i{
if(finish[i]==FALSE&&compare(request,work,n,i)==TRUE)//比较
{
for(j=0;j{
work[j]+=allocation[i][j];
}
finish[i]=TRUE;
p[i]=TRUE;//第i个进程放完资源
flag=TRUE;
break;
}
}
}
//********若所有的进程都放完,则返回ture,否则返回false**************
if(flag==FALSE)
{
for(i=0;iif(finish[i]==FALSE){K++;}
}
if(K>0){returnFALSE;}
elseif(K==0){returnTRUE;}
//**********************************************************
}
//解锁函数
voidjiesuo(int*work,int**request,int**allocation,int*finish,int*p,intm,intn)
{
inti,j,t,flag;
int*sum=newint[m];
for(i=0;isum[i]=0;
for(i=0;iif(p[i]==FALSE)
{
for(j=0;jsum[i]=sum[i]+allocation[i][j];
allocation[i][j]=0;
}
t=sum[0];
for(i=1;iif(tcout<<"撤消占资源最大的进程:
"<for(j=0;jwork[j]+=allocation[flag][j];
finish[flag]=TRUE;//完成flag进程的操作
p[flag]=FALSE;//不再对它进行判断
flag=check(work,request,allocation,finish,p,m,n);//判断是否已经解除死锁
if(flag==TRUE){cout<elsejiesuo(work,request,allocation,finish,p,m,n);//如果还没解除,继续放资源
}
voidjudge(int*work,int**request,int**allocation,int*finish,int*p,intm,intn)
{intflag;
flag=check(work,request,allocation,finish,p,m,n);//判断
if(flag==TRUE){cout<<"不会发生死锁!
"<else
{
cout<<"会发生死锁!
死锁进程如下:
"<for(inti=0;iif(p[i]==FALSE)cout<
cout<jiesuo(work,request,allocation,finish,p,m,n);//解锁
}
}
voidmain()//主函数
{
cout<<"死锁检测与解除算法示例"<intm=0;intn=0;inti,j;
cout<<"输入进程数m:
";
cin>>m;cout<cout<<"输入资源种类数n:
";
cin>>n;cout<int**allocation=newint*[m];//定义数组
int**max=newint*[m];
int**need=newint*[m];
int**request=newint*[m];
int*available=newint[n];
int*p=newint[m];
int*finish=newint[m];
int*work=newint[n];
for(i=0;ip[i]=FALSE;
cout<<"输入可用矩阵available[n]:
"<for(i=0;i{
cout<<"available["<
";
cin>>available[i];
cout<}
for(i=0;iallocation[i]=newint[n];
cout<<"输入已分配矩阵allocation[m][n]:
"<for(i=0;ifor(j=0;j{
cout<<"allocation["<
";
cin>>allocation[i][j];
cout<}
for(i=0;imax[i]=newint[n];
cout<<"输入最大需求矩阵max[m][n]:
"<for(i=0;ifor(j=0;j{
cout<<"max["<
";
cin>>max[i][j];
cout<}
for(i=0;ineed[i]=newint[n];
cout<<"需求矩阵为need[m][n]:
"<for(i=0;ifor(j=0;j{need[i][j]=max[i][j]-allocation[i][j];
cout<cout<for(i=0;irequest[i]=newint[n];
cout<<"请输入请求矩阵request[m][n]:
"<for(i=0;ifor(j=0;j{
cout<<"request["<
";
cin>>request[i][j];
cout<}
cout<for(i=0;ifinish[i]=TRUE;//初始标记为true
for(j=0;j{
if(allocation[i][j]>0||request[i][j]>0)
{
finish[i]=FALSE;
}
}
}
for(j=0;j{
work[j]=available[j];//初始情况
}
judge(work,request,allocation,finish,p,m,n);//开始判断
}
四、调试结果:
以上显示为未发生死锁的调试结果
发生死锁,经解锁算法,撤销占资源最大进程,死锁状况成功解除
五、心得体会:
通过该实验熟悉了指针的基本使用方法,死锁的检测与解除和银行家算法的数据结构基本相同,至于实验中所实施的死锁解除算法也只是简单撤销某一引起死锁进程所占有资源的简单释放,该实验只是简单模拟了死锁的检测与解除;最大的收获是对死锁定理的理解和对死锁解除算法的认识与实现机理实记。