一:银行家算法中的数据结构
1)可利用资源向量Available
是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。
2)最大需求矩阵Max
这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
3)分配矩阵Allocation
这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。
4)需求矩阵Need。
这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。
Need[i,j]=Max[i,j]-Allocation[i,j]
二:银行家算法
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。
(2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];
系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
三.安全性算法
1)设置两个向量:
工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available;
工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时,再令Finish[i]=true。
2)从进程集合中找到一个能满足下述条件的进程:
Finish[i]=false;
Need[i,j]≤Work[j];若找到,执行 (3),否则,执行 (4)
3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]=Work[i]+Allocation[i,j];
Finish[i]=true;
go to step 2;
4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
四.代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int Available[10] = { 0/*3, 3, 2*/ };//可利用资源
int Max[100][10] = { 0/*7, 5, 3, 3, 2, 2, 9, 0, 2, 2, 2, 2, 4, 3, 3*/ }; //最大需求矩阵
int Allocation[100][10] = {0 /*0, 1, 0, 2, 0, 0, 3, 0, 2, 2, 1, 1, 0, 0, 2*/ }; //当前已分配资源矩阵
int Need[100][10] = { 0 }; //进程还需要的资源
int SafeSeq[10] = { 0 }; //安全序列
int N, M;
void scan() //信息录入
{
int i = 0,j = 0;
printf("请输入资源数:");
scanf("%d", &N);
printf("请输入进程数:");
scanf("%d", &M);
printf("请输入资源:");
for (i = 0; i < N; i++)
{
scanf("%d", &Available[i]);
}
printf("请输入每个进程的最大资源需求量:");
for (i = 0; i < M;i++)
{
for (j = 0; j < N; j++)
{
scanf("%d", &Max[i][j]);
}
}
printf("请输入每个进程的已分配资源需求量:");
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++)
{
scanf("%d", &Allocation[i][j]);
}
}
}
void InitWork(int Work[])//Work矩阵初始化
{
int i;
for (i = 0; i < N; i++)
Work[i] = Available[i];
}
void InitNeed() //Need矩阵初始化
{
int i, j;
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
Need[i][j] = Max[i][j] - Allocation[i][j];
}
void Print() //打印函数
{
int i, j;
printf("-------------------------------------------------------\n");
printf("进程 Max Allocation Need Available\n");
for (i = 0; i < M; i++)
{
printf("P%d", i);
printf(" ");
for (j = 0; j < N; j++)
{
printf("%2d", Max[i][j]);
}
printf(" ");
for (j = 0; j < N; j++)
{
printf("%2d", Allocation[i][j]);
}
printf(" ");
for (j = 0; j < N; j++)
{
printf("%2d", Need[i][j]);
}
printf(" ");
if (i == 0)
{
for (j = 0; j < N; j++)
{
printf("%2d", Available[j]);
}
}
printf("\n");
}
printf("-------------------------------------------------------\n");
}
int NeedExamine(int Request[],int n) //银行家算法Need检查
{
int i;
for (i = 0; i < N; i++)
{
if (Request[i] > Need[n][i])
break;
}
if (i==N)
return 1;
return 0;
}
int AvailableExamine(int Request[])//银行家算法Available检查
{
int i;
for (i = 0; i < N; i++)
{
if (Request[i] > Available[i])
break;
}
if (i == N)
return 1;
return 0;
}
void Distribution(int Request[], int n)//资源分配
{
int i;
for (i = 0; i < N; i++)
{
Available[i] = Available[i] - Request[i];
Allocation[n][i] = Allocation[n][i] + Request[i];
Need[n][i] = Need[n][i] - Request[i];
}
}
void Banker(int Request[], int n)//银行家算法
{
if (NeedExamine(Request,n) == 0)
{
printf("请求错误!\n");
}
else if (AvailableExamine(Request) == 0)
{
printf("资源数不够!请求错误!\n");
}
else
{
Distribution(Request, n);
}
}
int ReturnNumTure(char *Finish[])//判断Finish中ture的个数
{
int i,num=0;
for (i = 0; i < M; i++)
{
if (strcmp(Finish[i], "T") == 0)
num++;
}
return num;
}
void Safe(int Work[], char *Finish[])
{
int i,j,k;
int count = 0;
b:i = -1;
a:while (i<M-1)// 如果小于5.当i为4是进去增1,数组越界
{
i++;
if (strcmp(Finish[i], "F") == 0)
{
for (j = 0; j < N; j++)
{
if (Need[i][j] > Work[j])
break;
}
if (j == N) //当前进程可执行
{
SafeSeq[count++] = i;
for (k = 0; k < N; k++)
{
Work[k] = Work[k] + Allocation[i][k];//执行完成,释放资源
}
Finish[i] = "T";//修改完成标志
if (i == M-1 && ReturnNumTure(Finish) != M)
goto b;
else
goto a;
}
}
}
if (ReturnNumTure(Finish) == M)
{
printf("安全!\n");
}
else
{
printf("不安全!\n");
}
}
int main()
{
int i;
int Request[10] = {0};
int Work[10] = {0};
char *Finish[10] = { "F", "F", "F", "F", "F", "F", "F", "F", "F", "F" };
int n;
scan();
InitNeed();//Need矩阵初始化
Print();
printf("请输入请求的进程号(0-%d):",M);
scanf("%d", &n);
printf("请输入请求的三类资源数:");
for (i = 0; i < N; i++)
{
scanf("%d",&Request[i]);
}
Banker(Request, n);//银行家算法
Print();
InitWork(Work);//Work矩阵初始化
Safe(Work, Finish);//安全检查
printf("安全序列是:");//安全序列打印
for (i = 0; i < M; i++)
printf("P%d ",SafeSeq[i]);
printf("\n");
return 0;
}