姓名:崔升 学号:14020120005
参考文献:http://blog.csdn.net/qq_34328833/article/details/53455000
【嵌牛导读】:
解决死锁问题的一个著名算法,银行家算法。
【嵌牛鼻子】:死锁的出现,常常导致内存溢出,造成大量的资源浪费,甚至造成系统崩溃
【嵌牛提问】:什么是进程死锁问题?死锁问题出现的原因?
【嵌牛正文】:死锁的定义>
如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那仫该组进程就是死锁的.
1).互斥条件:进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求资源只能等待,直至占有该资源的进程用毕释放.
2).请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已经被其他进程占有,此时请求进程被保持,但对自己所获得的资源又保持不放.
3).不可抢占条件:进程已获得的资源在未使用完之前不可被抢占,只能在使用完成后自己释放.
4).环路等待:在发生死锁时,必然存在一个进程,资源的循环链.
死锁产生的原因>
1).竞争可重用不可抢占式的资源
2).竞争可消耗资源
3).进程推进顺序不当.
可重用性资源:可供重复使用多次的资源.
不可抢占性资源:一旦系统把某资源分配给该进程后,就不能将它强行收回,只能在进程使用完后自动释放.
可消耗资源:又叫临时性资源,它是在进程运行期间,由进程动态的创建和消耗的.
利用银行家算法解决死锁>
1).银行家算法中的数据结构
(1).可利用资源向量Available
(2).最大需求矩阵Max
(3).分配矩阵Allocation
(4).需求矩阵Need
2).银行家算法
Request请求向量,
(1).如果Request[i] <= Need[i][j]转下步,否则它所需要的资源数已超过它所需要的最大值
(2).如果Request[i] <= Available[i][j]转下步,否则尚无足够资源,进程需等待
(3).系统试分配给进程p,并修改Available,Allocation和Need
Available[j] -= Request[j]
Allocation[i][j] += Request[j]
Need[i][j] -= Request[j]
(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态.若安全,才正式分配;否则恢复原来的分配状态,让该进程等待
3).安全性算法
(1).设置两个向量,工作向量Work,在执行安全性算法开始时 Work=Available;Finish:表示有足够的资源分配给进程,使之运行完成,Finish[i]=false;当有足够资源分配给进程时,再另Finish[i]=false
(2).从进程集合中找到一个满足该条件的进程:
Finish[i]=false
Need[i][j] <= Work[j]
(3).当进程获得资源后,可顺利执行,并修改Work向量和Finsh向量
Work[i] += Allocation[i][j]
Finish[i]=true
(4).如果所有进程的Finish[i]=true说明系统处于安全状态,否则系统处于不安全状态.
实现这份代码的时候陷入了一个误区那就是当你找到了一个安全序列之后,它查找过的Finish必定会被修改为true,而Finish这个数组又是在全局定义的,所以只要找到一次正确的安全序列这个Finish所找到的位就会被置为true会一直出现找到安全序列的,所以在找到安全序列之后一定要将Finish重新赋初值false,这个问题让我排错了半天,在定义变量的时候最好不要定义为全局的。
以下为代码实现(java)
constintMAXPROCESS=100;
constintMAXRESOURCE=100;
intAvailable[MAXRESOURCE];//可用资源向量
intMax[MAXPROCESS][MAXRESOURCE];//最大需求矩阵
intAllocation[MAXPROCESS][MAXRESOURCE];//分配矩阵
intNeed[MAXPROCESS][MAXRESOURCE];//需求矩阵
intRequest[MAXRESOURCE];//请求向量
intWork[MAXRESOURCE];//工作向量
boolFinish[MAXPROCESS];
intSafeSeries[MAXPROCESS];//安全序列
intn;//进程数
intm;//资源数
voidInit()
{
cout<<"请输入进程总数>";
cin>>n;
cout<<"请输入资源种类数>";
cin>>m;
inti,j;
printf("请输入%d类资源的当前可利用资源数目>\n",m);
for( i = 0; i < m; ++i )
{
cin >> Available[i];
}
printf("最大需求矩阵(%d*%d输入)>\n",n,m);
for( i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j )
{
cin >> Max[i][j];
}
}
printf("分配矩阵(%d*%d输入)>\n",n,m);
for( i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j )
{
cin >> Allocation[i][j];
}
}
printf("需求矩阵(%d*%d输入)\n",n,m);
for( i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j )
{
cin >> Need[i][j];
}
}
}
boolIsSafe()
{
inti=0;
for(i=0;i
{
if(Finish[i] ==true)
continue;
else
break;
}
if(i == n)
returntrue;//安全
else
returnfalse;//不安全
}
boolSelect(int&tmp,inttmpNeed[][MAXRESOURCE])
{
//选择一个Finish[i]=false,Need[i]<=Work[i]
intj=0;
for(inti=0;i
{
if(Finish[i])
continue;
for(j=0;j
{
if(tmpNeed[i][j] > Work[j])
break;
}
if(j == m)
{
tmp=i;
returntrue;
}
}
returnfalse;
}
boolSafe(int*tmpAvail,inttmpAlloc[][MAXRESOURCE],inttmpNeed[][MAXRESOURCE])
{
for(inti = 0; i < n; ++i)
{
Finish[i] =false;
}
for(intj = 0; j < m; ++j)
{
Work[j] = tmpAvail[j];
}
inttmp=0;
intindex = 0;
while(Select(tmp,tmpNeed))
{
Finish[tmp] =true;
for(intk = 0; k < m; ++k)
{
Work[k] += tmpAlloc[tmp][k];
}
SafeSeries[index++] = tmp;
}
if(IsSafe())
returntrue;//安全
else
returnfalse;//不安全
}
voidDisplay()
{
inti=0;
intj=0;
cout<<"当前可利用的资源数目"<
for(i = 0; i < m; ++i)
{
cout << Available[i]<<" ";
}
cout<
cout<<"最大需求矩阵"<
for(i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j)
{
cout<
}
cout<
}
cout<<"分配矩阵"<
for( i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j )
{
cout<
}
cout<
}
cout<<"需求矩阵"<
for( i = 0; i < n; ++i )
{
for( j = 0; j < m; ++j )
{
cout<
}
cout<
}
}
voidBankA()
{
inti=0;
intindex=0;
cout<<"请输入请求资源的进程下标>";
cin>>index;
assert(index < n && index >= 0);
cout<<"请输入当前的请求资源>"<
for(i=0;i
{
cin>>Request[i];
}
for(i=0;i
{
if(Request[i] <= Need[index][i])
{
continue;
}
else
{
cout<<"第一次试分配失败"<
break;
}
}
if(i < 3)//如果第一次试分配失败则不执行后面的语句
{
return;
}
for(i=0;i
{
if(Request[i] <= Available[i])
{
continue;
}
else
{
cout<<"第二次试分配失败"<
break;
}
}
if(i < 3)//如果第二次试分配失败则不同执行后面的语句
{
return;
}
//开始试分配
inttmpAvail[MAXRESOURCE]={0};
inttmpAlloc[MAXPROCESS][MAXRESOURCE]={0};
inttmpNeed[MAXPROCESS][MAXRESOURCE]={0};
memmove(tmpAvail,Available,sizeof(int)*MAXRESOURCE);
memmove(tmpAlloc,Allocation,sizeof(int)*MAXPROCESS*MAXRESOURCE);
memmove(tmpNeed,Need,sizeof(int)*MAXPROCESS*MAXRESOURCE);
for(inti=0;i
{
tmpAvail[i] -= Request[i];
tmpAlloc[index][i] += Request[i];
tmpNeed[index][i] -= Request[i];
}
//开始执行安全性算法
boolret=Safe(tmpAvail,tmpAlloc,tmpNeed);
if(ret ==true)
{
//如果试分配成功则更新Available,Allocation,Allocation的状态
memmove(Available,tmpAvail,sizeof(int)*MAXRESOURCE);
memmove(Allocation,tmpAlloc,sizeof(int)*MAXPROCESS*MAXRESOURCE);
memmove(Need,tmpNeed,sizeof(int)*MAXPROCESS*MAXRESOURCE);
cout<<"进程p"<
}
else
{
//只要试分配失败则将Finish置为false
for(inti = 0; i < n; ++i)
{
Finish[i] =false;
}
cout<<"第三次试分配失败"<
}
}
voidMenu()
{
cout<<"*************银行家算法*************"<
cout<<"**********1.测试安全性代码**********"<
cout<<"**********2.测试银行家算法**********"<
cout<<"**********3.初始化******************"<
cout<<"**********4.打印矩阵****************"<
cout<<"**********0.退出********************"<
}
以下为测试代码:
voidtestBank()
{
intindex=0;
intflag=1;
while(flag)
{
Menu();
cout<<"请输入您的选择"<
cin>>index;
switch(index)
{
case1:
Safe(Available,Allocation,Need);
if(IsSafe())
{
cout<<"该时刻是安全的,安全序列为>";
for(inti = 0; i < n ; ++i)
{
printf("p%d->",SafeSeries[i]);
}
cout<<"end"<
//分配成功将Finish的值置为false
for(inti = 0; i < n; ++i)
{
Finish[i] =false;
}
}
else
{
cout<<"该时刻是不安全的"<
}
break;
case2:
BankA();
if(IsSafe())
{
cout<<"安全序列为>";
for(inti = 0; i < n ; ++i)
{
printf("p%d->",SafeSeries[i]);
}
cout<<"end"<
//分配成功将Finish的值置为false
for(inti = 0; i < n; ++i)
{
Finish[i] =false;
}
}
else
{
cout<<"进程请求资源不被允许"<
}
break;
case3:
Init();
break;
case4:
Display();
break;
case0:
flag=0;
break;
default:
cout<<"您的输入错误,请重新输入"<
break;
}
}
}