在资源分配前,判断系统是否处于安全状态,如处于安全状态则把资源分配给申请进程,如处于不安全状态则令申请资源的进程堵塞,不响应其资源申请。银行家算法的核心理念就是把资源分配给那些最容易执行完成的进程,保证系统中各进程都能正常完成。
#include <stdio.h>
#include <stdlib.h>
#define N 100
#define M 50
int Available[N]; //可利用资源数组
int Max[M][N]; //最大需求矩阵
int Allocation[M][N]; //分配矩阵
int Need[M][N]; //需求矩阵
int Request[M][N]; //M 个进程还需要 N 类资源的资源量
int Finish[M]; //在安全检测函数里标记进程是否被使用过
int p[M]; //安全运行进程的顺序记录,会用在advice函数里
int Adv; //Adv提示你该输入哪个进程。
int m,n; //m 个进程,n 类资源
int Safe();
void print();
void advice();
int Safe()
{
int i,j,l=0;
int Work[100]; //可利用资源数组
for (i=0;i<n;i++)
Work[i]=Available[i];
for (i=0;i<m;i++)
Finish[i]=0;
for (i=0;i<m;i++)
{
if (Finish[i]==1)
continue;
else
{
for (j=0;j<n;j++) //如果该进程中所有需要的资源数都小于可提供的资源数,则不会触发break。
{
if (Need[i][j]>Work[j])
break;
}
if (j==n) //表示该进程安全
{
Finish[i]=1;
for(int k=0;k<n;k++)
Work[k]+=Allocation[i][k]; //将进程所占有的资源释放回计算机
p[l++]=i; //记录进程被释放的顺序,用于advice函数上。
i=-1; //这步很关键
}
else continue;
}
if (l==m)
{
printf("系统是安全的\n");
printf("系统安全序列是:\n");
for (i=0;i<l;i++)
{
printf("%d",p[i]);
if (i!=l-1)
printf("-->");
}
printf("\n");
return 1;
}
}
return 0;
}
解释一下为什么要 i=-1,那就先举个栗子吧!!
假设进程数为3,资源数为2。可利用资源Available[ ]分别为 1、2。各个进程还需要的资源Need[ ][ ]分别为P0:3、4。 P1:2、3。 P2:1、2。为了例子能举简单些,让Need[ ][ ]等于Allocation[ ][ ]
Available[ ]
资源类型 | 资源数 |
---|---|
A | 1 |
B | 2 |
Need [ ]
进程类型 | 资源类型A | 资源类型B |
---|---|---|
P0 | 3 | 4 |
P1 | 2 | 3 |
P2 | 1 | 2 |
如果没有i=-1会怎么运行?
if (Need[i][j]>Work[j]) break;这条语句只会在P2时不执行break,但执行for语句时i==m,跳出了for循环。会检测出不能安全运行的错误。
本来可以P2–>P1–>p0安全运行,但因为少了i=-1。产生了逻辑错误
void advice()
{
int i,j=0;
int count=0;
Adv=p[count]; //先选定P[0]为第一个建议输出的进程
for (i=0;i<m;i++)
{
if (count!=i) //当count不等于i时,表示找到了推荐的进程。
break;
for (j=0;j<n;j++) //如果这个进程需要资源,那么就推荐这个进程
if (Need[Adv][j]!=0)
break;
if (j==n) //如果上一个进程不需要资源就指向下一个P[]数组里的进程号
{
count++;
Adv=p[count];
}
}
}
#include <stdio.h>
#include <stdlib.h>
#define N 100
#define M 50
int Available[N]; //可利用资源数组
int Max[M][N]; //最大需求矩阵
int Allocation[M][N]; //分配矩阵
int Need[M][N]; //需求矩阵
int Request[M][N]; //M 个进程还需要 N 类资源的资源量
int Finish[M]; //在安全检测函数里标记进程是否被使用过
int p[M]; //安全运行进程的顺序记录
int Adv; //Adv提示你该输入哪个进程。
int m,n; //m 个进程,n 类资源
int Safe();
void print();
void advice();
int main()
{
int mi;
int i,j;
// int Max[N][M],Available[M],Allocation[N][M],Need[N][M];
printf("请输入进程数:");
scanf("%d",&m);
printf("请输入资源数:");
scanf("%d",&n);
printf("请输入最大需求矩阵Max:\n");
printf("\tMax\n\t");
for (j=0;j<n;j++)
printf("%c\t",'A'+j);
printf("\n");
for (i=0;i<m;i++)
{
printf("P%d\t",i);
for (j=0;j<n;j++)
{
scanf("%d",&Max[i][j]);
}
}
printf("请输入分配矩阵Allocation:\n");
printf("\tAllocation\n\t");
for (j=0;j<n;j++)
printf("%c\t",'A'+j);
printf("\n");
for (i=0;i<m;i++)
{printf("P%d\t",i);
for (j=0;j<n;j++)
{
scanf("%d",&Allocation[i][j]);
}
}
printf("请输入分配矩阵Need:\n");
printf("\tNeed\n\t");
for (j=0;j<n;j++)
printf("%c\t",'A'+j);
printf("\n");
for (i=0;i<m;i++)
{ printf("P%d\t",i);
for (j=0;j<n;j++)
{
Need[i][j]=Max[i][j]-Allocation[i][j];
printf("%d",Need[i][j]);
printf("\t");
}
printf("\n");
}
printf("请输入分配矩阵Available:\n");
printf("\tAvailable\n\t");
for (j=0;j<n;j++)
printf("%c\t",'A'+j);
printf("\n\t");
for (j=0;j<n;j++)
{
scanf("%d",&Available[j]);
}
printf("\n");
print();
Safe();
while (1)
{
advice();
printf("输入要申请的资源的进程号:(1,2,3...)\t");
printf("(建议你输入%d)\n",Adv);
scanf("%d",&mi);
printf("你实际输入的资源的进程号:%d\n",mi);
printf("输入进程所请求的各个资源的数量\t");
printf("建议你输入:");
for (j=0;j<n;j++)
printf("%d\t",Need[mi][j]);
printf("\n");
printf("你实际输入的各个资源的数量:");
for (i=0;i<n;i++)
scanf("%d",&Request[mi][i]);
printf("\n");
for (i=0;i<n;i++)
{
if (Request[mi][i]>Need[mi][i])
{
printf("所请求资源数超过进程的需求量\n");
return 0;
}
if (Request[mi][i]>Available[i])
{
printf("所请求资源数超过系统所有的资源数!\n");
return 0;
}
}
for (i=0;i<n;i++)
{
Available[i]-=Request[mi][i];
Allocation[mi][i]+=Request[mi][i];
Need[mi][i]-=Request[mi][i];
}
if (Safe())
{
printf("同意分配请求\n");
for (i=0;i<n;i++)
if (Need[mi][i]!=0)
break;
if(i==n)
{
for (i=0;i<n;i++)
{
Available[i]=Available[i]+Request[mi][i]+Allocation[mi][i];
Allocation[mi][i]=0;
}
}
print();
}
else
{
printf("SORRY你的请求被拒绝\n");
for (i=0;i<n;i++)
{
Available[i]+=Request[mi][i];
Allocation[mi][i]-=Request[mi][i];
Need[mi][i]+=Request[mi][i];
}
}
for (i=0;i<m;i++)
Finish[i]=0;
char Flag; //标志位
printf("是否再次请求分配?是请按 Y/y,否请按 N/n");
while (1)
{
scanf("%c",&Flag);
if (Flag=='Y'||Flag=='y'||Flag=='N'||Flag=='n')
break;
else
{
printf("请按要求重新输入:\n");
continue;
}
}
if (Flag=='Y'||Flag=='y')
continue;
else break;
}
return 0;
}
void advice()
{
int i,j=0;
int count=0;
Adv=p[count]; //先选定P[0]为第一个建议输出的进程
for (i=0;i<m;i++)
{
if (count!=i) //当count不等于i时,表示找到了推荐的进程。
break;
for (j=0;j<n;j++) //如果这个进程需要资源,那么就推荐这个进程
if (Need[Adv][j]!=0)
break;
if (j==n) //如果上一个进程不需要资源就指向下一个P[]数组里的进程号
{
count++;
Adv=p[count];
}
}
}
int Safe()
{
int i,j,l=0;
int Work[100]; //可利用资源数组
for (i=0;i<n;i++)
Work[i]=Available[i];
for (i=0;i<m;i++)
Finish[i]=0;
for (i=0;i<m;i++)
{
if (Finish[i]==1)
continue;
else
{
for (j=0;j<n;j++) //如果该进程中所有需要的资源数都小于可提供的资源数,则不会触发break。
{
if (Need[i][j]>Work[j])
break;
}
if (j==n) //表示该进程安全
{
Finish[i]=1;
for(int k=0;k<n;k++)
Work[k]+=Allocation[i][k]; //将进程所占有的资源释放回计算机
p[l++]=i; //记录进程被释放的顺序,用于advice函数上。
i=-1; //这步很关键
}
else continue;
}
if (l==m)
{
printf("系统是安全的\n");
printf("系统安全序列是:\n");
for (i=0;i<l;i++)
{
printf("%d",p[i]);
if (i!=l-1)
printf("-->");
}
printf("\n");
return 1;
}
}
return 0;
}
void print()
{
int i,j,flag=0;
printf("\t\tMax\t\t\tAllocation\t\tNeed\n");
for (i=0;i<3;i++)
for (j=0;j<n;j++)
printf("\t%c",'A'+j);
printf("\n");
for (i=0;i<m;i++)
{
printf("P%d\t",i);
for (j=0;j<n;j++)
printf("%d\t",Max[i][j]);
for (j=0;j<n;j++)
printf("%d\t",Allocation[i][j]);
for (j=0;j<n;j++)
printf("%d\t",Need[i][j]);
printf("\n");
}
printf("\tAvailable\n");
for (j=0;j<n;j++)
printf("\t%c",'A'+j);
printf("\n");
for (j=0;j<n;j++)
printf("\t%d",Available[j]);
printf("\n");
}
这是我的第一篇博客,如有不足,请各位大佬不吝赐教。谢谢!