【银行家算法】
银行家算法是迪杰斯特拉先生的又一创作,主要用于解决操作系统上的死锁问题。问题大概是,选择当前进程操作,能否保证之后,不会出现死锁问题。核心思想是,先检查当前进程的资源数是否能得到满足,可以的话,创建一个执行了当前进程的新状态,并用while循环去逐一寻找可被执行的进程,若最后所有进程都能被执行,则返回安全状态信息,并执行当前进程,反之则返回不安全信息,并阻塞该进程。
代码实现:
/*
Authour: david_jett
Time:2015/12/8 23:06
Content:banker's algorithm
*/
#include <iostream>
#include <cstring>
#define m 3 //资源种类
#define n 4 //进程数
struct state
{
int resource[m];
int available[m];
int claim[n][m];
int alloc[n][m];
}P;
using namespace std;
int request[m];
//judge the current state according to banker's algorithm
bool is_Safe(state tmp,int x)
{
bool status[n];
int cnt=1,pos;
memset(status,0,sizeof(status));
status[x]=1;
bool flag=0;
while(1)
{
bool flag=0;
for(int i=0;i<n;i++)
{
if(!status[i])
{
flag=1;
for(int j=0;j<m;j++)
{
if(tmp.claim[i][j]-tmp.alloc[i][j]>tmp.available[j])
{
flag=0;
break;
}
}
if(flag)
{
pos=i;
status[i]=1;
break;
}
}
}
if(flag)
{
cnt++;
for(int i=0;i<m;i++)
{
tmp.available[i]+=tmp.alloc[pos][i];
tmp.alloc[pos][i]=0;
tmp.claim[pos][i]=0;
}
}
else break;
}
if(cnt==n)return true;
else return false;
}
//update the state if legal
void Update(state tmp)
{
for(int i=0;i<m;i++)
P.available[i]=tmp.available[i],
P.resource[i]=tmp.resource[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
P.claim[i][j]=tmp.claim[i][j];
P.alloc[i][j]=tmp.alloc[i][j];
}
}
}
//calculate the requested amount
void Create_request(int x)
{
for(int i=0;i<m;i++)
request[i]=P.claim[x][i]-P.alloc[x][i];
}
int Allocate(int x)
{
//Exception
for(int i=0;i<m;i++)
if(P.alloc[x][i]+request[i]>P.claim[x][i])
return 1;
//Suspend process
for(int i=0;i<m;i++)
if(request[i]>P.available[i])
return 2;
//Define a newstate
state tmp;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
tmp.claim[i][j]=P.claim[i][j];
for(int i=0;i<m;i++)
{
tmp.resource[i]=P.resource[i];
tmp.claim[x][i]=0;
tmp.available[i]=P.available[i]+P.alloc[x][i];
tmp.alloc[x][i]=0;
}
/*Judge whether the new state is safe or not, if it is ,
update the state or return the exception message.*/
if(is_Safe(tmp,x))
{
Update(tmp);
return 0;
}
else
return 2;
}
bool Initialize()
{
for(int i=0;i<m;i++)
{
P.available[i]=P.resource[i];
for(int j=0;j<n;j++)
P.available[i]-=P.alloc[j][i];
if(P.available[i]<0)
return false;
}
return true;
}
int main()
{
//get resource amount
printf("Resource Amount:\n");
for(int i=0;i<m;i++)
scanf("%d",&P.resource[i]);
//get claim matrix
printf("Claim matrix:\n");
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&P.claim[i][j]);
//get allocation matrix
printf("Allocation matrix:\n");
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&P.alloc[i][j]);
//Calculate request
if(Initialize())
{
printf("Please Input the ID of the process you wanna check.\n");
int x;
scanf("%d",&x);
//calculate the requested resource amount
Create_request(x);
printf("Requested Amount:\n");
for(int i=0;i<m;i++)
printf("%d ",request[i]);
printf("\n");
int flag=Allocate(x);
if(!flag)
printf("P%d is Okay!\n");
else if(flag==1)
printf("An exception has occured!\n");
else
printf("P%d has been suspended!\n",x);
}
else
{
printf("An exception has occured!\n");
}
return 0;
}