死锁的检测与解除.docx
《死锁的检测与解除.docx》由会员分享,可在线阅读,更多相关《死锁的检测与解除.docx(22页珍藏版)》请在冰豆网上搜索。
![死锁的检测与解除.docx](https://file1.bdocx.com/fileroot1/2023-1/2/b4b306e9-ca87-4cc7-9e83-0406f362b487/b4b306e9-ca87-4cc7-9e83-0406f362b4871.gif)
死锁的检测与解除
死锁的检测与解除
--操作系统实验报告
题目:
死锁的检测与解除
指导老师:
班级:
姓名:
学号:
时间:
实验二死锁的检测与解除
一、实验目的
系统为进程分配资源时并不一定能满足进程的需求,因此检测系统的安全性是非常有必要的。
安全性的检测在之前的实验中用银行家算法得以实现,此次实验增加了另一个问题:
即当系统死锁时如何解除死锁。
通过此次实验,可以深刻的体会死锁的检测与解除的方法。
二、实验内容
编程实现死锁的检测与解除,并上机验证。
实验环境:
MicrosoftVisualStudio2010
三、算法描述
程序中的数据结构:
1)可用资源向量
:
这是一个含有
个元素的数组,其中的每一个元素代表一类可利用资源数目。
2)最大需求矩阵
:
它是一个
的矩阵,定义了系统中n个进程中得每一个进程对
类资源的最大需求。
3)可分配矩阵
:
这也一个
的矩阵,定义了系统中每一类资源当前已分配给每一进程的资源数。
4)需求矩阵
:
这表示每一个进程尚需的各类资源数。
5)综上所述:
。
该程序是在银行家算法的基础上添加了死锁的解除模块得来的,死锁的解除采用的方法是:
找到已分配资源最大的死锁进程,剥夺其已分配资源,再次检测是否发生死锁。
1)设
是进程
的请求向量,如果
,表示进程
需要
个
类型起源。
当
发出资源请求后,进行检查,如果合格,修改
、
、
的值。
2)用安全性算法检查是否存在安全序列,如果存在,输出安全序列;如果不存在,即为死锁,进行解锁操作。
3)统计
的值,找出占用资源最多的进程
,将其撤销,回收占用的资源,修改一下的数据结构中的值:
;
;
用安全性算法进行检查,如果仍有死锁,重复步骤3,知道解锁为止。
4)输出安全序列。
程序主要包括四大模块,一是输入数据模块,二是资源请求模块,三是检测死锁模块,四是对死锁进行解除模块。
程序流程图如下:
四、程序清单及简单注释
//死锁的检测与解除.
#include
#include
#include
#defineTRUE1
#defineFALSE0
usingnamespacestd;
intnumber=0;//定义全局变量,number为请求资源的进程号
intnum=0;//num为安全序列中进程的个数
intInput();
intoutput();
//******输出未解锁之前的资源分配情况*******
intoutput(int**max,int**need,int*work,int**allocation,intm,intn)
{inti,j,mark=1;
cout<<"该时刻的资源分配情况如下:
"<cout<cout<<"各个矩阵:
|max|allocation|need|available|"<cout<cout<<"Process|Rescource|";
for(i=0;i<4;i++)
{
for(j=0;j{
cout<<"["<cout<<"";
}
cout<<"|";
}
cout<cout<cout<<"-----------------------------------------------------------"<for(i=0;i{
cout<<"P["<
cout<<"|";
for(j=0;j{
cout<}
cout<<"|";
for(j=0;j{
cout<}
cout<<"|";
for(j=0;j{
cout<}
cout<<"|";
if(mark==1)
{
for(j=0;j{
cout<}
cout<<"|";
mark=0;
}
cout<}
cout<getchar();
return0;
}
//********输出解锁之后的资源分配情况***********
intoutput2(int**need,int**allocation,int*work,int*ss,int*finish,int*p,intm,intn)
{inti,j,mark=1,tag;
cout<<"该时刻的资源分配情况如下:
"<cout<cout<<"各个矩阵:
|need|allocation|work|wor+allocation|finish|"<cout<cout<<"Process|Rescource|";
for(i=0;i<4;i++)
{
for(j=0;j{
cout<<"["<cout<<"";
}
cout<<"|";
}
cout<cout<cout<<"-----------------------------------------------------------"<for(i=0;i{
tag=ss[i];
cout<<"P["<cout<<"|";
for(j=0;jcout<cout<<"|";
for(j=0;jcout<cout<<"|";
for(j=0;jcout<cout<<"|";
for(j=0;j{
cout<work[j]=work[j]+allocation[tag][j];
}
cout<<"|";
if(finish[tag]=1)
cout<<"TRUE"<<"";
else
cout<<"FALSE"<<"";
cout<<"|";
cout<}
getchar();
return0;
}
//*************输入所有相关的信息*************
intInput(int**max,int**need,int*work,int**allocation,int*available,int*request,intm,intn,intflag)
{
intj;
cout<<"请输入请求资源的进程号:
";
cin>>number;
cout<if(number>=n)
{
returnFALSE;
}
else
{
for(j=0;j{
cout<<"进程P["<";//输入请求向量request
cin>>request[j];
cout<}
for(j=0;j{
if(request[j]>need[number][j]||request[j]>available[j])//判断请求向量的合法性
flag=FALSE;
}
returnflag;
}
}
//***********可用资源与需求矩阵的比较************
intcheck(int**need,int*work,intN,inti)
{
intj,c=0;
for(j=0;j{
if(need[i][j]>work[j])
{
c++;}
}
if(c>0)returnFALSE;
elseif(c==0)returnTRUE;
}
//*******************系统安全性的检测******************
intjudge(int**need,int*work,int**allocation,int*finish,int*p,int*ss,intm,intn)
{inti,j,k=0,count=0,flag=TRUE,mark=0,tag=0;
while(flag==TRUE)
{flag=FALSE;
for(i=0;i{
if(finish[i]==FALSE&&check(need,work,n,i)==TRUE)
{
for(j=0;jwork[j]=work[j]+allocation[i][j];//进程请求成功,完成作业后回收allocation的资源
finish[i]=TRUE;
p[i]=TRUE;
flag=TRUE;
ss[tag++]=i;//存储进程,用于输出安全序列
break;
}
}
}//while(flag==TRUE)
if(flag==FALSE)
{
for(i=0;iif(finish[i]==FALSE)
{
k++;
}
}
if(k>0)
{
cout<cout<<"检测结果:
存在死锁进程!
"<cout<returnFALSE;
}
if(k==0)
{cout<cout<<"检测结果:
不存在死锁进程!
"<cout<cout<<"输出安全序列为:
";
for(i=0;icout<<"P["<cout<getchar();
cout<returnTRUE;
}
}
//********************解锁***********************
voidunlock(int**need,int*available,int*work,int**allocation,int*finish,int*p,int*ss,intm,intn)
{
//统计死锁进程的资源数,找出最大的死锁进程,进行撤销
int*sum=newint[m],i,j,k=0,count2=0,flag;
int*temp=newint[n];//用于暂存work数组里的值,间接调用request函数
for(i=0;itemp[i]=work[i];
for(i=0;i{
if(finish[i]==FALSE)
{
for(j=0;jsum[i]=sum[i]+allocation[i][j];//寻找占用资源最多的进程
}
}
count2=sum[0];
for(i=0;i{
if(sum[i]>count2)
{
count2=sum[i];
k=i;//k标记的数组位置即为已分配资源最多的进程
}
}
cout<<"撤销占用资源最大的进程P["<for(i=0;i{
work[i]=work[i]+allocation[k][i];
}
finish[k]=TRUE;//完成对该进程的操作
p[k]=FALSE;//不再对该进程进行判断
num--;
flag=judge(need,work,allocation,finish,p,ss,m,n);//再次进行判断是否存在安全序列
if(flag==TRUE)
{
cout<cout<<"成功解除死锁!
"<output2(need,allocation,work,ss,finish,p,m,n);
for(i=0;i{
allocation[number][i]=allocation[number][i]-available[i]+temp[i];
need[number][i]=need[number][i]+available[i]-temp[i];
}//恢复请求进程原始的资源分配
finish[k]=FALSE;//初始化对该进程的操作
p[k]=TRUE;//初始化对该进程进行判断
num++;//恢复撤销进程之前的情况
for(j=0;jwork[j]=available[j];//初始化work数组
cout<getchar();
}
else
unlock(need,available,work,allocation,finish,p,ss,m,n);
}
//*******************主函数***************
voidmain()
{
inti,j,m,n,count=0,s=0;
intflag=FALSE;
charname;
cout<cout<<"请输入进程数m:
";
cin>>m;
num=m;
cout<cout<<"请输入资源数n:
";
cin>>n;
cout<int**max=newint*[m];
int**need=newint*[m];
int**allocation=newint*[m];
int*request=newint[n];
int*available=newint[n];
int*finish=newint[m];
int*p=newint[m];
int*work=newint[n];
int*ss=newint[m];
for(i=0;i{
max[i]=newint[n];
need[i]=newint[n];
allocation[i]=newint[n];
}
cout<<"请输入各个进程对各种资源的最大需求max:
"<cout<for(i=0;ifor(j=0;j{
cout<<"进程P["<
";//输入max矩阵
cin>>max[i][j];
cout<}
cout<<"请输入已分配的矩阵allocation:
"<cout<for(i=0;ifor(j=0;j{
cout<<"进程P["<
";//输入allocation矩阵
cin>>allocation[i][j];
if(allocation[i][j]>max[i][j])
{
cout<cout<<"输入数据大于最多需求数,重新输入!
"<j--;
}
elseneed[i][j]=max[i][j]-allocation[i][j];
cout<}
cout<<"请输入可分配的资源available:
"<cout<for(i=0;i{
cout<<"["<
";//输入available向量
cin>>available[i];
work[i]=available[i];
cout<}
for(i=0;i{
finish[i]=FALSE;//输入finsish向量
p[i]=FALSE;
}
output(max,need,work,allocation,m,n);//输出目前的资源分配情况
cout<i=0;
while(flag==FALSE&&i{flag=TRUE;
for(j=0;jwork[j]=available[j];
for(j=0;j{
ss[j]=0;
}//初始化缓存数组ss
for(j=0;j{
finish[j]=FALSE;
p[j]=FALSE;
}//初始化各进程分配情况
flag=Input(max,need,work,allocation,available,request,m,n,flag);
if(flag==TRUE)
{
for(j=0;j{
available[j]=available[j]-request[j];
work[j]=available[j];
need[number][j]=need[number][j]-request[j];
allocation[number][j]=allocation[number][j]+request[j];
}//修改请求资源后的资源分配情况
cout<<"输出此时的资源分配情况:
"<cout<output(max,need,work,allocation,m,n);
flag=judge(need,work,allocation,finish,p,ss,m,n);
if(flag==TRUE)
{
output2(need,allocation,work,ss,finish,p,m,n);
}
else
{
cout<<"存在死锁进程!
"<cout<cout<<"输出死锁的进程:
";
for(i=0;i{
if(finish[i]==FALSE)
cout<<"P["<
}
cout<cout<<"是否要进行解锁!
解锁请输入'Y',不解锁请输入'N':
";
cin>>name;
cout<if(name=='Y')
{
unlock(need,available,work,allocation,finish,p,ss,m,n);
}
else
{
cout<<"程序运行结束!
"<break;
}
}//else
flag=FALSE;
}
else
{
cout<if(number{
cout<<"请求的资源数超过所拥有的资源数,进程P["<"<cout<}
else
{
cout<<"不存在进程P["<"<}
}
i++;
}//while(flag==FALSE&&igetchar();
}
五、实验结果
开始输入:
输入最大需求矩阵max:
输入已分配矩阵allocation:
输入可用资源向量available:
此时资源分配情况如下:
进程P[1]请求资源:
(请求成功)
进程P[1]请求资源:
(请求资源数超过可用资源)
进程P[2]请求资源:
(发生死锁)
检测到死锁产生,进行解锁:
如果一次解锁不成功,则继续剥夺下一个已分配资源最多的死锁进程的资源,直到死锁解除。
经检查,实验结果符合要求。
六、实验小结
通过这次实验,我对死锁的各方面理解都有了更深层次的认识。
一开始,对于死锁的解除,我只是从第一个进程开始剥夺其资源,也不管它是不是发生了死锁,一直剥夺到死锁解除为止。
然后,我又对程序进行改进,让其可以判断死锁进程与非死锁进程,然后从第一个死锁进程开始剥夺已分配资源。
到最后,我又对程序进一步完善,让其判断一下在死锁进程中,哪个的已分配资源最多,就先剥夺它的资源,直到死锁解除。
通过以上这几次对程序的改进,我不仅对死锁的解除有了更进一步的理解,也加深了对编程理念的认识。
一种好的编程习惯、编程理念不仅可以帮助减少工作量,更可以帮助编程人员对程序的思想进行全面理解,对程序需求进行全面理解。