银行家算法的模拟与实现

在学习银行家算法之前,我们首先要了解以下几个概念:

死锁:多个进程在执行过程中,因为进程资源会造成相互等待的局面。如果没有外力作用,这些进程将永远无法向前推进。此时称系统处于死锁状态或者系统产生了死锁。

安全序列:某系统按某种顺序并发进程,并使它们都能达到获得最大资源而顺序完成序列为安全序列。

安全状态:能找到安全序列的状态称为安全状态。安全状态不会导致死锁。

不安全状态:在当前状态下不存在安全序列,则系统处与不安全状态。

注:安全状态一定不死锁,死锁一定不安全,但不安全 不一定死锁

img

我们需要了解到操作系统的中,进程的三态模型

这就要问了:什么是进程?

定义:系统总正在运行的一个程序,比如我们现在打开的浏览器就可以说是一个进程

接下来我们来说说进程的三种基本状态:

一、就绪状态(Ready):

进程以获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器资源,进程就可以执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进行就绪状态时,排入低优先队列;当进程有I/O操作完成而进入就绪状态时,排入高优先队列。

二、运行状态(Running):

进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。(空闲进程:Windows页面内存管理进程。)

三、阻塞状态(Blocked):

由于进程等待某种条件(如I/O操作或进程同步),在条件满足之前无法继续执行。该事件发生前即使把处理器资源分配给该进程,也无法运行。

三种状态转换如下图所示:

进程的三个基本状态

银行家算法

介绍:银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要满足多个客户的借贷周转,

为了防止银行家资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。

在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须

保证得到的资源的进程能在有限的时间内归还资源,以供其它进程使用资源。如果资源分配不当,

就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。

当一进程提出资源申请时,银行家算法执行下列步骤以决定是否向其分配资源:

1)检查该进程所需要的资源是否已超过它所宣布的最大值。

2)检查系统当前是否有足够资源满足该进程的请求。

3)系统试探着将资源分配给该进程,得到一个新状态。

4)执行安全性算法,若该新状态是安全的,则分配完成;若新状态是不安全的,则恢复原状

态,阻塞该进程。

以下是银行家算法所用到的主要数据结构:

1)可用资源向量available:它记录系统中各类资源的当前可利用数目。它是个含m个元素的数组,其中每一个元素代表一类可利用的资源数目,即Available[jJ=K,表示系统中现有j类资源K个。

2)最大需求矩阵max:它是记录每个进程对各类资源的最大需求量。这是一个n×m的矩阵,如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵allocation:它记录每个进程当前对各类资源当前的占有量。这也是一个n×m的矩阵,如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。

4)需求矩阵need:它记录每个进程都各类资源尚需要的数目,等于最大需求矩阵与分配矩阵的差。

5)请求向量request:它记录某个进程对当前资源的申请量,是银行家算法的入口参数。

通过上面的学习,接下来,我们对银行家算法进行如下的描述:

由上面可以知道”请求向量request“是银行家算法的入口,所以设进程Pi先系统提出requesti资源请求

(1)如果requesti>need,进程Pi出错

(2)如果requesti>available,进程Pi阻塞

(3)系统试着把资源分配给进程Pi,并对相应数据结构做如下修改:

available-request;allocation+request,need-request

(4)系统执行安全性检测子算法,以判断试分配后系统状态是否安全

(5)如果(4)返回逻辑真值,即”安全“,则完成本次分配,返回

(6)否则,撤销本次试分配,进程阻塞

img

具体代码如下:

#include<iostream>

#include<stdio.h> using namespace std;

// p 进程数,r资源种类

int p ;

int r ;

int maxs[10][10]; //最大需求矩阵

int allocation[10][10]; //分配矩阵

int need[10][10]; //需求矩阵

int available[10]; //可用资源向量

int request[10]; //请求向量当前进程对各类资源的申请量,算法的入口参数 //输入函数

void infInput() {

int i,j; cout<<"请输入最大需求矩阵max\n";

for(i=0; i<p; i++) {

for(j=0; j<r; j++) {

cin>>maxs[i][j];

}

}

cout<<"请输入分配矩阵allocation\n";

for(i=0; i<p; i++) {

for(j=0; j<r; j++) {

cin>>allocation[i][j];

}

}

cout<<"请输入需求矩阵need\n";

for(i=0; i<p; i++)

{

for(j=0; j<r; j++)

{

cin>>need[i][j];

}

}

cout<<"请输入可用资源向量available\n";

for(i=0; i<r; i++) {

cin>>available[i];

}

}

//比较函数 //比较进程为m中的元素全大于n中的元素返回1,否则返回0

int compare(int m[],int n[])

{

int i;

for(i=0; i<r; i++) {

if(m[i]<n[i]) {

return 0;

}

}

return 1;

}

//安全性检验函数,检测是否存在安全序列

int stest() {

int i,j,k,l,flag=0; int finish[p]; int work[r]; for(i=0; i<p; i++) {

finish[i]=0; //vis为1即表示available满足第i进程的资源需要

}

for(i=0; i<r; i++)

{

work[i]=available[i];

}

cout<<"分配序列:\n"; cout<<" allocation need avilable"<<endl;

for(k=0; k<p; k++)

{

for(i=0; i<p; i++)

{

if(finish[i]==1)

{

continue;

}

else {

if(compare(work,need[i]))//available>=need 

{

finish[i]=1; cout<<'\n'<<"进程"<<i+1<<'\t'; flag=1;

for (j =0; j<r; j++) {

printf(" %2d ", allocation[i][j]);

}

cout<<" ";

for (j = 0; j < r; j++) {

printf(" %2d ", need[i][j]);

}

cout<<" "; for (j = 0; j <r; j++)

{

printf(" %2d ", work[j] +allocation[i][j]);

}

for(l=0; l<r; l++)

{

work[l]=work[l]+allocation[i][l]; //进程完成,释放资源 }

break;

}

}

if(flag==1)

{

break;

}

}

}

cout<<'\n'; for(l=0; l<p; l++)

{

if(finish[l]==0)

{

return 0;//不存在安全序列

}

}

return 1;//存在安全序列

}

//申请进程后的安全性检验函数

void rtest(int n)

{

int j; //n=n-1;

if(compare(available,request)&&compare(need[n-1],request))//available>=request 并且 need >=request { for(j=0; j<r; j++)

{

allocation[n-1][j]=allocation[n-1][j]+request[j];

need[n-1][j]=need[n-1][j]-request[j];

available[j]=available[j]-request[j];

}

if(stest())

{

cout<<"允许"<<n<<"进程申请资源!\n";

}

else

{

cout<<"不允许"<<n<<"进程申请资源!\n";

for(j=0; j<r; j++)

{

allocation[n-1][j]=allocation[n-1][j]-request[j];

need[n-1][j]=need[n-1][j]+request[j];

available[j]=available[j]+request[j];

}

}

}

else

{

cout<<"申请资源量越界!\n";

}

}

int main()

{

int i,n; //n-第n个资源申请

cout<<"请输入进程数:";

cin>>p;

cout<<"请输入资源种类数:";

cin>>r; //默认状态4、3 infInput();//输入函数 if(stest()==1) {

cout<<"存在安全序列,初始状态安全。\n";

}

else {

cout<<"不存在安全序列,初始状态不安全。\n";

}

cout<<"请输入发出请求向量request的进程编号:";

cin>>n;

cout<<"请输入请求向量request\n";

for(i=0; i<r; i++)

{

cin>>request[i];

}

rtest(n);

return 0;

}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值