#include <stdio.h>
#define N 5
#define M 3
int p[N]={0,1,2,3,4};
int r[M]={10,5,7};
int Available[M]; //资源总剩余量
int Need[N][M]; //每个进程还需要多少资源
int Max[N][M] = { //一共需要多少资源
{7,5,3},
{3,2,2},
{9,0,2},
{2,2,2},
{4,3,3}
};
int Allocation[N][M] = { //已经分配了多少资源
{0,1,0},
{2,0,0},
{3,0,2},
{2,1,1},
{0,0,2}
};
void init();
void prt();
int isSafe();
int request[M]; //请求的资源列表
int x; //请求资源的进程号
int main(){
init();
prt();
//输入一个资源请求,判断该请求是否应该被分配
printf("请输入要请求资源的进程号(0-4之间)");
scanf("%d",&x);
printf("请输入要请求资源的数量,以空格分开");
scanf("%d %d %d",&request[0],&request[1],&request[2]);
if(isSafe() == 1){
printf("安全,可以分配!\n");
}else{
printf("不安全,不可以分配!\n");
}
return 0;
}
void init(){ //初始化,计算Need和Availa的值
int i,j;
int sum[M] = {0};
for(i=0;i<N;i++){
for(j=0;j<M;j++){
Need[i][j] = Max[i][j]-Allocation[i][j];
sum[j] += Allocation[i][j];
}
}
for(j=0;j<M;j++){
Available[j] = r[j] - sum[j];
}
}
void prt(){ //输出矩阵
int i,j;
printf(" Max Avaliable Need \n");
for(i=0;i<N;i++){
printf("进程%d|",p[i]);
for(j=0;j<M;j++){
printf("%3d",Max[i][j]);
}
putchar('|');
for(j=0;j<M;j++){
printf("%3d",Allocation[i][j]);
}
putchar('|');
for(j=0;j<M;j++){
printf("%3d",Need[i][j]);
}
putchar('\n');
}
printf("Available:%2d%2d%2d\n",Available[0],Available[1],Available[2]);
}
int isSafe(){
int i,j,k;
int sq[N] = {0};
for(j=0;j<M;j++){
if(request[j] > Available[j] || request[j] > Need[x][j]){ //如果请求的数量大于可用资源数量或大于需要的资源数量,则不能分配
return 0;
}
}
printf("进程%d分配%2d%2d%2d\n",x,request[0],request[1],request[2]);
for(j=0;j<M;j++){ //更新矩阵
Allocation[x][j] += request[j];
Need[x][j] -= request[j];
Available[j] -= request[j];
}
prt();
//寻找安全序列
for(k=0;k<N;k++){ //寻找N个进程的安全序列
for(i=0;i<N;i++){
if (sq[i] == 1){ //第i个进程已经进入到了安全序列
continue;
}
for(j=0;j<M;j++){
if(Available[j] < Need[i][j]){ //该进程无法被分配
break;
}
}
if (j < M){ //因为break而退出,说明进程i不合适,继续找i+1
continue;
}
for(j=0;j<M;j++){ //对进程i全部分配资源
Available[j] += Allocation[i][j];
Allocation[i][j] = Max[i][j];
Need[i][j] = 0;
}
sq[i] = 1; //进程i进入安全序列
printf("进程%d\n",i);
prt();
break;
}
if(i >= N){ //因为break退出,所以没有找到任何进程可以分配,说明无法寻找到安全序列
return 0;
}
}
return 1;
}