一、银行家算法概念
银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
安全序列:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。
不安全状序列:不存在一个安全序列。不安全状态不一定导致死锁。
二、实验环境
首先本机是 Windows10 家庭版
visual studio 2019
Intelcore i7-8550U CPU
三、实验题目
编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性。
例3-1某系统有A、B、C、D4类资源共5个进程(PO、P1、P2、P3、P4)共享,
各进程对资源的需求和分配情况如表3-1所示。
表3-1各进程对资源的需求和分配情况表
进程 已占资源 最大需求数
A B C D A B C D
P0 0 0 1 2 0 0 1 2
P1 1 0 0 0 1 7 5 0
P2 1 1 5 4 2 3 5 6
P3 0 6 3 2 0 6 5 2
P4 0 0 1 1 0 6 5 6
现在系统中A、B、C、D4类资源分别还剩1、5、2、0个,请按银行家算法回答下列问题:
①现在系统是否处于安全状态?
②如果现在进程Pl提出需要(0、4、2、0)个资源的请求,系统能否满足它的请求?
四、实验步骤
银行家算法
Step1:如果Request[i]<=Need[i],则转向Step2;否则,出错。
Step2:如果Request[i]<=Available[i],则转向Stcp3;否则,出错。
Step3:系统试探分配相关资源,修改相关数据:
Available[i]=available[i]-Request[i]
Allocation[i]=allocation(i]+Request[i]
Need[i]-need[i]-request[i]
Step4:系统执行安全性检查,如安全,则分配成立;否则试探性分配资源作废,系统恢复原状,进程进入等待状态。
安全性检查算法
Step1:设置两个工作向量Work=Available,Finish=false;
Step2:从进程集合中找到一个满足下述条件的进程;
Finish=false,
Need<=Work,
如果能够找到该进程,则执行Step3,否则,执行Step4
Step3:假设上述找到的进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=work+Allocation,
Finish=true,
GotoStep2
Step4:如果所有进程的Finish=true,则表示该系统安全;否则系统不安全。
五、实验代码
#include <iostream>
using namespace std;
//全局变量定义
int Available[100]; //可利用资源数组
int Max[50][100]; //最大需求矩阵
int Allocation[50][100]; //分配矩阵
int Need[50][100]; //需求矩阵
int Request[50][100]; //M个进程还需要N类资源的资源量
int Finish[50];
int p[50];
int m, n; //M个进程,N类资源
//安全性算法
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++)
{
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;
i = -1;
}
else continue;
}
if (l == m)
{
cout << "系统是安全的" << '\n';
cout << "系统安全序列是:\n";
for (i = 0; i < l; i++)
{
cout << p[i];
if (i != l - 1)
cout << "-->";
}
cout << '\n';
return 1;
}
}
}
//银行家算法
int main()
{
int i, j, mi;
cout << "输入进程的数目:\n";
cin >> m;
cout << "输入资源的种类:\n";
cin >> n;
cout << "输入每个进程最多所需的各类资源数,按照" << m << "x" << n << "矩阵输入\n";
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
cin >> Max[i][j];
cout << "输入每个进程已经分配的各类资源数,按照" << m << "x" << n << "矩阵输入\n";
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
cin >> Allocation[i][j];
Need[i][j] = Max[i][j] - Allocation[i][j];
if (Need[i][j] < 0)
{
cout << "你输入的第" << i + 1 << "个进程所拥有的第" << j + 1 << "个资源错误,请重新输入:\n";
j--;
continue;
}
}
}
cout << "请输入各个资源现有的数目:\n";
for (i = 0; i < n; i++)
cin >> Available[i];
Safe();
while (1)
{
cout << "输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
cin >> mi;
cout << "输入进程所请求的各个资源的数量\n";
for (i = 0; i < n; i++)
cin >> Request[mi][i];
for (i = 0; i < n; i++)
{
if (Request[mi][i] > Need[mi][i])
{
cout << "所请求资源数超过进程的需求量!\n";
return 0;
}
if (Request[mi][i] > Available[i])
{
cout << "所请求资源数超过系统所有的资源数!\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())
cout << "同意分配请求\n";
else
{
cout << "你的请求被拒\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; //标志位
cout << "是否再次请求分配?是请按Y/y,否请按N/n";
while (1)
{
cin >> Flag;
if (Flag == 'Y' || Flag == 'y' || Flag == 'N' || Flag == 'n')
break;
else
{
cout << "请按要求重新输入:\n";
continue;
}
}
if (Flag == 'Y' || Flag == 'y')
continue;
else break;
}
}
六、实验结果
关于银行家算法就不多说了,详细见下一篇博客。会对银行家算法再进行一次详细介绍!!
制作人:只识闲人不识君
日期:2020.06.25