银行家算法

(一)实验目的
(1)进一步理解利用银行家算法避免死锁的问题;
(2)在了解和掌握银行家算法的基础上,编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再检测和笔算的一致性。
(3)理解和掌握安全序列、安全性算法。
(二)实验内容及要求
(1)了解和理解死锁;
(2)理解利用银行家算法避免死锁的原理;
(3)会使用某种编程语言。
(三)程序框架及算法
一、初始化
由用户输入数据,分别对可利用资源向量矩阵AVAILABLE、最大需求矩阵MAX、分配矩阵ALLOCATION、需求矩阵NEED赋值。
(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]
二、银行家算法
在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
三、安全性检查算法
(1)设置两个工作向量Work=AVAILABLE;FINISH
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work+=ALLOCATION;
Finish=true;
GOTO 2
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。

初始化算法流程图:

在这里插入图片描述

银行家算法流程图:

在这里插入图片描述
安全性算法流程图:
在这里插入图片描述
源程序清单

#include
using namespace std;
#define MAXPROCESS 50 /最大进程数/
#define MAXRESOURCE 100 /最大资源数/
int AVAILABLE[MAXRESOURCE]; /可用资源数组/
int MAX[MAXPROCESS][MAXRESOURCE]; /最大需求矩阵/
int ALLOCATION[MAXPROCESS][MAXRESOURCE]; /分配矩阵/
int NEED[MAXPROCESS][MAXRESOURCE]; /需求矩阵/
int REQUEST[MAXPROCESS][MAXRESOURCE]; /进程需要资源数/
bool FINISH[MAXPROCSS]; /系统是否有足够的资源分配/
int p[MAXPROCESS]; /记录序列/
int m,n; /m个进程,n个资源/
void Init();
bool Safe();
void Bank();
int main()
{
Init(); /初始化算法/
Safe(); /安全性算法/
Bank(); /银行家算法/
}
void Init() /初始化算法/
{
int i,j;
cout<<“请输入进程的数目:”;
cin>>m;
cout<<“请输入资源的种类:”;
cin>>n;
cout<<“请输入每个进程最多所需的各资源数,按照”<<m<<“x”<<n<<“矩阵输入”<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>MAX[i][j];
cout<<“请输入每个进程已分配的各资源数,也按照”<<m<<“x”<<n<<“矩阵输入”<<endl;
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<<“个资源数错误,请重新输入:”<<endl;
j–;
continue;
}
}
}
cout<<“请输入各个资源现有的数目:”<<endl;
for(i=0;i<n;i++)
{
cin>>AVAILABLE[i];
}
}

C语言
源代码:
#include
using namespace std;
const int Max_process = 50;//最大进程数
const int Max_source = 50;//最大资源数
class bank
{
private:
int available[Max_source];//可用资源数
int max[Max_process][Max_source];//最大需求
int allocation[Max_process][Max_source];//已分配资源数
int need[Max_process][Max_source];//还需资源数
int request[Max_process][Max_source];//进程需要资源数
bool finish[Max_process];//判断系统是否有足够的资源分配
int p[Max_process];//记录序列
int m;//用来表示进程
int n;//表示资源

public:
void Init();//完成对变量的初始化
bool Safe();//安全检测算法
void Banker();//银行家算法
void Display(int, int);//显示进程与资源状态

};

void bank::Init()
{
cout << “请输入进程的数目:”;
cin >> m;
cout << “请输入资源的数目:”;
cin >> n;
cout << “请输入每个进程最多所需的各资源数,按照” << m << ‘X’ << n << “矩阵格式输入” << endl;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> max[i][j];
cout << “请输入每个进程已分配的各资源数,按照” << m << ‘X’ << n << “矩阵格式输入” << endl;
for (int i = 0; i < m; i++)
for (int 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 << “请输入各个资源现有的数目” << endl;
for (int i = 0; i < n; i++)
{
cin >> available[i];可用资源数
}
}
//m表示进程,n表示资源
void bank::Display(int n, int m)
{
cout << endl << “+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++” << endl;
cout << “系统可用的资源数为:”;
for (int i = 0; i < n; i++)
{
cout << available[i] << " ";
}
cout << endl << “各进程最多需要的资源数:” << endl;
for (int i = 0; i < m; i++)
{
cout << “P” << i << “:”;
for (int j = 0; j < n; j++)
{
cout << " " << max[i][j];
}
cout << endl;
}
cout << endl << “各进程已经得到的资源:” << endl;
for (int i = 0; i < m; i++)
{
cout << “P” << i << “:”;
for (int j = 0; j < n; j++)
{
cout << " " << allocation[i][j];
}
cout << endl;
}
cout << endl << “各进程还需要的资源量:” << endl;
for (int i = 0; i < m; i++)
{
cout << “P” << i << “:”;
for (int j = 0; j < n; j++)
cout << " " << need[i][j];
cout << endl;
}
cout << endl << endl;
}

void bank::Banker()
{
int num_process, flag = 0;//num_process表示资源进程号
char again;//键盘录入一个字符用于判断是否继续请求资源
while (1)
{
Display(n, m);
cout << endl;
/请求资源/
while (true)
{
cout << “请输入要申请的进程号:”;
cin >> num_process;
if (num_process > m)
{
cout << “没有该进程,请重新输入” << endl;
continue;
}
cout << “请输入进程所请求的各资源数:” ;
for (int i = 0; i < n; i++)
cin >> request[num_process][i];
for (int i = 0; i < n; i++)
{
if (request[num_process][i] > need[num_process][i])
{
cout << “你输入的资源请求数超过进程数需求量!请重新输入” << endl;
continue;
}
if (request[num_process][i] > available[i])
{
cout << “你输入的资源请求数超过系统当前资源拥有数!” << endl;
break;
}
}
break;
}
/上述是资源请求不合理的情况,下面是资源请求合理时则执行银行家算法/
for (int i = 0; i < n; i++)
{
available[i] -= request[num_process][i];//可用资源减去成功申请的
allocation[num_process][i] += request[num_process][i];//已分配资源加上成功申请的
need[num_process][i] -= request[num_process][i];//进程还需要的减去成功申请的
}
/判断分配申请资源后系统是否安全,如果不安全则将申请过的资源还给系统/
if (Safe())//安全性算法
cout << “同意分配请求!”<<endl;
else
{
cout << “你的请求被拒绝! !!” << endl;
/进行向系统还回资源操作/
for (int i = 0; i < n; i++)
{
available[i] += request[num_process][i];
allocation[num_process][i] -= request[num_process][i];
need[num_process][i] += request[num_process][i];
}
}
/判断是否继续申请/
cout << “你还想再次请求分配吗?是请按Y/y,否请按其他键!” << endl;
cin >> again;
if (again == ‘Y’ || again == ‘y’)
continue;
break;
}
}
m表示进程,n表示资源
bool bank::Safe()
{
int l = 0, j, i;
int work[Max_source];//工作向量,系统可提供给进程继续运行所需各类资源数
/对work数组进行初始化,初始化时和avilable可用资源数数组相同/
for (int i = 0; i < n; i++)
work[i] = available[i];
/对finish数组(判断系统是否有足够的资源分配)初始化全为false/
for (int i = 0; i < m; i++)
finish[i] = false;
for (int i = 0; i < m; i++)
{
if (finish[i] == true)
continue;
else
{
for (j = 0; j < n; j++)
{
if (need[i][j] > work[j])
break;
}
if (j == n)
{
finish[i] = true;
for (int k = 0; k < n; k++)
work[k] += allocation[i][k]; //已分配+work(可分配)
p[l++] = i;//记录进程号
i = -1;保证每次查询均从第一个进程开始
}
else
continue;
}
}
if (l == m)//进程数
{
cout << “系统是安全的” << endl;
cout << “安全序列:” << endl;
for (int i = 0; i < l; i++)
{
cout << p[i];
if (i != l - 1)
cout << “–>”;
}
cout << endl << endl;
return true;
}
}
int main()
{
cout << “------------------------------------------------” << endl;
cout << endl << endl;
cout << " 银行家算法" << endl;
cout << endl << endl;
cout << “------------------------------------------------” << endl;
bank peter;
peter.Init();
peter.Safe();
peter.Banker();
return 0;
}

运行程序,首先需要输入进程的数目和资源的数目,每个进程最多所需的各资源数、已分配的各资源数和各个资源现有的数目,运行及输入情况如下图所示:
在这里插入图片描述
在分配资源之前,首先会判断当前初始状态是否为安全状态,若处于安全状态,则提示系统是安全的,并输出安全序列,允许资源分配。反之,若处于不安全状态,则不允许后续的资源分配。
在这里插入图片描述
开始进行分配资源,首先输入要申请的进程号,输入进程所请求的各资源数;根据申请进行安全性检查,如果处于安全状态,则允许分配,并输出安全序列。分配完成后如果想要再次分配,输入y/Y,否则输入其它符号:
在这里插入图片描述
输入y再次请求分配资源,同样首先输出当前系统可用的资源数、各进程最多需要的资源数、各进程已经得到的资源、各进程还需要的资源量输出。
在这里插入图片描述
输入申请3进程,但由于此时3进程需要资源数小于申请的资源数,因此提示输入的资源请求数超过进程数需求量,并重新输入。结果图如下所示:
在这里插入图片描述

总结:通过不断查阅资料,修改代码,最终完成了实验。本实验由几个模块组成,先是对于进程所需资源里和剩余资源里的计算,然后调用显示函数,将所有的资源数里以及进程的各种数里显示出来,接着就是银行家算法的主体,通过用户输入的进程分配第一个资源,接着由程序自行判断,用银行家算法变成资源预分配状态,接着运用安全检测函数检测与分配的安全性,如果安全责则输出安全序列,分配成功,否则资源请求不合理再重新调配资源。银行家算法是一种最具有代表性的避免死锁的算法,通过这个实验,我也真正理解了操作系统在为进程分配资源的过程,对理论课的学习有了进一步的理解。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习使我哈皮!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值