银行家算法是避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2)顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金。
这是典型的安全状态避免死锁的问题。
银行家算法中数据结构主要是几个数组:
1、可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果Available[j]=K,则表示系统中现有类资源K个。
2、最大需求矩阵Max。这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要类资源的最大数目为K。
3、分配矩阵Allocation。这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得类资源的数目为K。
4、需求矩阵Need。这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要类资源K个,方能完成其任务。
由数学知识易得
Need[i, j]=Max[i, j]-Allocation[i, j]
下面给出每个模块的思路:
初始化:
由用户输入数据,分别对可利用资源向量矩阵AVAILABLE、 最大需求矩阵MAX、分配矩阵ALLOCATION、需求矩阵NEED赋值。
银行家模块:
设是进程的请求向量,如果=K,表示进程需要K个类型的资源。当发出资源请求后,系统按下述步骤进行检查:
(1) 如果<=Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。
(2) 如果≤Available[j],便转向步骤(3);否则,表示尚无足够资源,须等待。
(3) 系统试探着把资源分配给进程,并修改下面数据结构中的数值:
Available[j] = Available[j]-;
Allocation[i,j] = Allocation[i,j]+;
Need[i,j] = Need[i,j]-;
(4) 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程等待。
安全性检查模块:
(1)设置两个向量:
① 工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work:=Available。
② Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]:=false;当有足够资源分配给进程时,再令Finish[i]:=true。
(2) 从进程集合中找到一个能满足下述条件的进程:
① Finish[i]=false;
② Need[i,j]≤Work[j];若找到,执行步骤(3),否则,执行步骤(4)。
(3) 当进程获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]:= Work[j]+Allocation[i,j];
Finish[i]:=true;
go to step (2);
(4) 如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
这里给出一个安全状态分配结果:
最后给出源码:(使用c++编写完成)
#include<iostream>
#include <stdio.h>
#include <string.h>
#include <iomanip>
using namespace std;
#define m_MAX 100 //最大资源数
#define n_MAX 50 //最大进程数
const int N = 1e3 + 10;
int process;//进程的个数
int resource;//资源的种类
int Available[m_MAX];//系统可用资源的数目
int Max[n_MAX][m_MAX];//每个进程对每类资源的最大需求量
int Allocation[n_MAX][m_MAX];//每类资源当前已分配个每一进程的资源数
int Need[n_MAX][m_MAX];//每个进程尚需各类资源的数目
int Request[n_MAX][m_MAX];//进程的请求向量
int p[n_MAX];//进程序列
int Resource[m_MAX];//每个资源的总数目
void Menu();
void Display();
void checkinit();
int Init();
bool Safecheck();
int banker();
void Menu()
{
cout << "------------------Banker----------------------" << endl;
cout << "* 1.初始化数据 *" << endl;
cout << "* 2.申请资源 *" << endl;
cout << "* 3.显示资源分配情况 *" << endl;
cout << "* 4.退出 *" << endl;
cout << "----------------------------------------------" << endl;
cout << "请选择:";
}
void Display()
{
cout << endl;
cout << "进程 \t Max \t Allocation\tNeed\tAvailable" << endl;
for (int i = 0; i < process; i++)
{
cout << " P" << i << " \t";
for (int j = 0; j < resource; j++)
{
cout << Max[i][j] << " ";
}
cout << "\t ";
for (int j = 0; j < resource; j++)
{
cout << Allocation[i][j] << " ";
}
cout << "\t";
for (int j = 0; j < resource; j++)
{
cout << Need[i][j] << " ";
}
cout << "\t ";
for (int j = 0; i == 0 && j < resource; j++)
{
cout << Available[j] << " ";
}
cout << endl;
}
cout << endl;
}
void checkinit()
{
if (resource)
for (int i = 0; i < process; i++)
{
for (int j = 0; j < resource; j++)
{
if (Max[i][j] < 0)
cout << "Max[" << i << "][" << j << "]输入值小于0!" << endl;
if (Allocation[i][j] < 0)
cout << "Allocation[" << i << "][" << j << "]输入值小于0!" << endl;
if (Allocation[i][j]>Max[i][j])
cout << "Allocation[" << i << "][" << j << "]的值大于Max[" << i << "][" << j << "]输入值" << endl;
}
}
for (int i = 0; i < resource; i++)
{
if (Available[i]<0)
cout << "Available[" << i << "]的值小于0!" << endl;
}
cout << "输入检查完毕,无错误输入!" << endl;
}
//初始化函数
int Init()
{
if (resource != 0 && process != 0)
{
cout << "你已经初始化过了!" << endl;
return 1;
}
int i, j;
cout << "请输入进程的数目:";
cin >> process;
cout << "请输入资源的种类:";
cin >> resource;
cout << "请输入各个资源的总数目:" << endl;
for (i = 0; i < resource; i++)
cin >> Resource[i];
for (i = 0; i < process; i++)
{
cout << "P" << i << "对各个资源的最大需求量:" << endl;
for (j = 0; j < resource; j++)
{
cin >> Max[i][j];
}
cout << "P" << i << "各个资源已分配量:" << endl;
for (j = 0; j < resource; j++)
{
cin >> Allocation[i][j];
}
for (j = 0; j < resource; j++)
{
Need[i][j] = Max[i][j] - Allocation[i][j];
if (Need[i][j]<0)
{
cout << "您输入的第" << i + 1 << "个进程所拥有的第" << j + 1 << "个资源数错误,请重新输入:" << endl;
j--;
continue;
}
}
}
for (int i = 0; i < resource; i++)
{
int sum[m_MAX] = { 0 };
for (int j = 0; j < process; j++)
{
sum[i] += Allocation[j][i];
}
Available[i] = Resource[i] - sum[i];
}
checkinit();
bool Is_safe = Safecheck();
if (Is_safe == true)
{
return 1;
}
else {
Init();
}
}
bool Safecheck()
{
int safe_list[n_MAX] = { 0 }, y = 0;//safe_list[]用于存放安全序列
int Work[m_MAX] = {0};//表示系统提供给进程继续运行所需的各类资源的数目
bool Finish[n_MAX] = {0};//表示系统是否有足够的资源分配给进程
cout << endl << "----------进入安全性检测--------------------" << endl;
for (int s = 0; s<resource; s++)
Work[s] = Available[s];
for (int z = 0; z<process; z++)
{
for (int s = 0; s < process;)
{
if (Finish[s] == 0)
{
for (int j = 0; j < resource; j++)
{
if (Need[s][j] > Work[j])
{
goto xx;
}
}
for (int m = 0; m < resource; m++)
{
Work[m] = Work[m] + Allocation[s][m];
}
Finish[s] = 1;
safe_list[y] = s;
y++;
}
xx:
s++;
}
}
if (y == process)
{
cout << "-----------检测结果:系统安全--------------------" << endl;
cout << "找到一个安全序列:";
for (int s = 0; s<process - 1; s++)
cout << "P" << safe_list[s] << "--->";
cout << "P" << safe_list[process - 1] << endl << "已通过安全检测!" << endl;
return 1;
}
cout <<"------------检测结果:系统不安全--------------------" << endl << "安全测试失败。" << endl;
cout << "--------------------安全性检测结束--------------------" << endl;
return 0;
}
int banker()
{
if (resource == 0 && process == 0) {
cout << "您还未进行初始化" << endl;
return 1;
}
int n ; //请求资源的进程号
cout << "请输入你要请求的进程号:";
cin >> n;
if (n > process)
{
cout << "没有该进程,请重新输入" << endl;
banker();
}
cout << "请输入你要请求各个资源的数量,中间用空格隔开:" << endl;
for (int i = 0; i < resource; i++)
{
cin >> Request[n][i];
}
//开始判断
for (int i = 0; i < resource; i++)
{
if (Need[n][i] < Request[n][i])
{
cout << "您输入的请求数超过进程的需求量!请重新输入" << endl;
banker();
}
}
for (int i = 0; i < resource; i++)
{
if (Available[i] < Request[n][i])
{
cout << "您输入的请求数超过系统现有的资源数!请重新输入" << endl;
banker();
}
}
//试分配资源给请求进程,并做安全性检查
for (int i = 0; i < resource; i++)
{
Available[i] -= Request[n][i];
Allocation[n][i] += Request[n][i];
Need[n][i] -= Request[n][i];
}
bool Is_safe= Safecheck();
if (Is_safe == true)
{
cout << "系统已经分配资源给P" << n << "进程了!" << endl;
}
else
{
cout << "您的请求被拒绝,系统会处于不安全状态!" << endl;
//恢复试分配之前的现场
for (int i = 0; i < resource; i++)
{
Available[i] += Request[n][i];
Allocation[n][i] -= Request[n][i];
Need[n][i] += Request[n][i];
}
}
return 1;
}
int main()
{
int choose ;
while (1)
{
Menu();
cin >> choose;
switch (choose)
{
case 1:
Init();
break;
case 2:
banker();
break;
case 3:
Display();
break;
case 4:
cout << "系统已退出!";
return 1;
default:
cout << "输错了,请重新输入" << endl;
break;
}
}
}