目录
一、实验内容
二、实验目的
三、实验原理
3.1、银行家算法中的数据结构
3.2、银行家算法
3.3、安全性算法
流程图:
代码实现:
银行家算法的实现。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。通过编写一个模拟动态资源分配的银行家算法程序,帮助学生进一步深入理解死锁、产生死锁的必要条件、安全状态等重要概念,并掌握避免死锁的具体实施方法。
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[j]+Allocation[i,j];
Finish[i]=true;
go to step 2;
4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态
#include
#include
#include
#pragma warning(disable:4996)
//定义系统内资源种类
#define M 3
//定于系统内进程数量
#define N 5
//定义全局变量
//定于系统内M种资源的总数量
int Resource[M];
//定义系统内N种进程对M种资源的最大需求量
int Max[N][M];
//定义系统内N种进程已分配M种资源的数量
int Allocation[N][M];
//定义系统内N种进程对M种资源的需求量
int Need[N][M];
//定义系统内M种资源可以用于分配的数量
int Available[M];
//定义安全性检查相关变量
int Work[M];
int Finish[N];
//定义用于存放安全序列的下标序列的集合
int List[N];
//构建算法初始状态:输入 Resource、Max和 Allocation,计算出 Need、Available。
void initial();
//打印当前系统的状态表|Process |Max |Allocation |Need |Available |
void printState();
/*
安全性检查:
1.返回同时满足两个条件{①Finish[i]=false; ②Need[i][j]≤Work[j]}的进程下标 i ,修改Finish[i]=true;
2.否则不通过安全性检查,返回结果为-1;
*/
int isFinish();
//判定当前状态是否为安全状态 ,把安全序列的下标放入 List[N]数组。
int isSafe();
//输出安全序列表|Process |Work |Need |Allocation |Work+Alloc |Finish |
void printList();
//定义第i个进程请求M类资源 request[M]
void reqresource(int i, int Request[M]);
//主函数
void main()
{
int index, j;
int req[M];
initial();
printState();
if (isSafe() == 0)
{
printf("初始化状态处于不安全状态!\n");
}
else
{
printf("\n初始状态为安全状态!\n");
printList();
printf("请输入申请资源的进程名(1~5):>");
scanf("%d", &index);
while (index >= 1 && index < N+1) //输入进程名是否合法
{
printf("请输入资源申请:>");
for (j = 0; j < M; j++)
{
scanf("%d", &req[j]);
}
reqresource(index-1, req);
printState();
printf("请输入申请资源的进程名(1~5):>");
scanf("%d", &index);
}
}
}
void initial()
{
int i, j;
printf("Resource--请输入M种资源的总数量:>\n");
for (i = 0; i < M; i++)
{
scanf("%d", &Resource[i]);
Available[i] = Resource[i];
}
printf("Max--请输入N个进程分别对M种资源的最大需求量:>\n");
for (j = 0; j < N; j++)
{
for (i = 0; i < M; i++)
{
scanf("%d", &Max[j][i]);
}
}
printf("Allocation--请输入N个进程获得M种资源的数量:>\n");
for (j = 0; j < N; j++)
{
for (i = 0; i < M; i++)
{
scanf("%d", &Allocation[j][i]);
}
}
//计算出N种进程对M种资源的需求矩阵
for (j = 0; j < N; j++)
{
for (i = 0; i < M; i++)
{
Need[j][i] = Max[j][i] - Allocation[j][i];
}
}
//计算出M种资源的可分配矩阵
for (j = 0; j < M; j++)
{
for (i = 0; i < N; i++)
{
Available[j] = Available[j] - Allocation[i][j];
}
}
}
void printState()
{
int i;
printf("状态表:\n|Process | Max |Allocation |Need |Available | \n");
for (i = 0; i < N; i++)
{
if (i == 0)
printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|\n", i, Max[i][0], Max[i][1], Max[i][2], Allocation[i][0], Allocation[i][1], Allocation[i][2], Need[i][0], Need[i][1], Need[i][2], Available[0], Available[1], Available[2]);
else
printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d| |\n", i, Max[i][0], Max[i][1], Max[i][2], Allocation[i][0], Allocation[i][1], Allocation[i][2], Need[i][0], Need[i][1], Need[i][2]);
}
}
int isFinish()
{
int i, j, count;
for (i = 0; i < N; i++)//M(3)种资源对N(5)个进程是否满足安全性检查
{
for (j = 0, count = 0; j < M; j++)
if (Finish[i] == 0 && Need[i][j] <= Work[j])
{
count++;
}
if (count == 3)//代表此进程可以完成
{
for (j = 0; j < M; j++)
{
Work[j] += Allocation[i][j]; //完成进程后释放资源
}
Finish[i] = 1;
return i;
}
}
return -1;
}
int isSafe()
{
int i, j;
int count = 0;
for (i = 0; i < M; i++)
Work[i] = Available[i];
for (i = 0; i < N; i++)
Finish[i] = 0;
for (i = 0; i < N; i++) //得出安全序列
{
j = isFinish();
if (j != -1)
{
List[i] = j;
count++;
}
}
if (count == 5)
return 1; //通过安全检查
else
return 0;
}
void printList()
{
int i, j;
printf("\n安全序列表如下:\n|Process |Work |Need |Allocation |Work+Alloc |Finish |\n");
for (j = 0; j < M; j++)
{
Work[j] = Available[j];
}
for (i = 0; i < N; i++)
{
printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|true\n", List[i], Work[0], Work[1], Work[2], Need[List[i]][0], Need[List[i]][1], Need[List[i]][2], Allocation[List[i]][0], Allocation[List[i]][1], Allocation[List[i]][2], Work[0] + Allocation[List[i]][0], Work[1] + Allocation[List[i]][1], Work[2] + Allocation[List[i]][2]);
for (j = 0; j < M; j++)
Work[j] += Allocation[List[i]][j];
}
}
void reqresource(int i, int Request[M])
{
int flag, count1, count2;
int j;
//步骤一: 判断条件 Request[j]≤Need[i][j]
for (j = 0, count1 = 0; j < M; j++)
{
if (Request[j] <= Need[i][j])
count1++;
}
//步骤二: 判断条件 Request[j]≤Available[j]
for (j = 0, count2 = 0; j < M; j++)
{
if (Request[j] <= Available[j])
count2++;
}
if (count2 != 3)
printf("\n此时无足够的资源,第%d个进程已堵塞。\n", i);
//步骤3: 模拟分配
if (count2 == 3 && count1 == 3) //步骤1与步骤2均已满足
{
for (j = 0; j < M; j++)
{
Available[j] = Available[j] - Request[j];
Allocation[i][j] = Allocation[i][j] + Request[j];
Need[i][j] = Need[i][j] - Request[j];
}
//安全性检查
if (isSafe() == 0)
{
printf("\n此时不存在安全序列,不是安全状态。\n");
for (j = 0; j < M; j++) //返回模拟分配前的状态
{
Available[j] = Available[j] + Request[j];
Allocation[i][j] = Allocation[i][j] - Request[j];
Need[i][j] = Need[i][j] + Request[j];
}
}
//通过安全性检查,进行资源分配
else
{
printf("\n此时是安全序列,系统资源分配成功!\n");
printList();
}
}
}