2021-06-25 银行家算法模拟

银行家算法模拟

核心思想:
先对用户提出的请求进行合法性检查,即检查请求的是否不大于需要的,是否不大于可利用的。
若请求合法,则进行试分配。
最后对试分配后的状态调用安全性检查算法进行安全性检查。
若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>

using namespace std;
const int maxn=50;  //假设最多有50类资源
const int maxm=30; //假设最多有30个进程

//银行家算法的数据结构
string resourceName[maxn];  //用来保存资源名称
string proName[maxm];  //用来保存进程名称
int Available[maxn];  //可以用的资源Available[i] 表示第i种资源的可利用数量
int Max[maxm][maxn];  //最大需求矩阵 Max[i][j] 第j个进程对第i中资源的最大需求量
int Allocation[maxm][maxn]; //每个进程对各类资源当前的占有量, Allocation[j][i]表示第j个项目已获取的第i类资源
int Need[maxm][maxn]; //表示每个进程对各类资源尚需要的数目Need = Max-Allocation
int Request[maxn];   //表示某个进程对当前各类资源的申请数量

//安全性子算法
int Work[maxn];  //表示系统可提供给进程继续运行所需要的各类资源的数目,初始Work=Available
bool Finish[maxn];//表示是否有足够的资源分配给进程使之运行完成,Finish[i]=true 表示当前系统的i类资源是可以满足当前进程的运行的
//最开始的时候Finish[i]=false,当有足够资源分配给进程时,Finish[i]=true
string Security[maxn]; //存放安全序列

//全局变量
int proNum;  //全局变量的数量
int resourceNum; //一共有多少类资源

//所有数组,下标从1开始,第一个进程,第一种资源
/*
核心思想:
先对用户提出的请求进行合法性检查,即检查请求的是否不大于需要的,是否不大于可利用的。 
若请求合法,则进行试分配。
最后对试分配后的状态调用安全性检查算法进行安全性检查。 
若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
*/
void initResources()
{
    for(int i=1;i<=resourceNum;i++)
    {
        Available[i] = rand()%10+1;  //最开始每类资源的数目在1~10之间,随机生成
        resourceName[i] = "R"+to_string(i);
    }
}
void initPro()
{
    //创建进程所需要的信息
    for(int i=1;i<=proNum;i++)
    {
        proName[i] = "P"+to_string(i);  //第i个进程
        for(int j=1;j<=resourceNum;j++)  //有resourceNum列
        {
            Max[i][j] = rand()%10; //0-10对该类资源的最大需求量
            Allocation[i][j] = rand()%8;  //已拥有的该类资源0-8
            if(Max[i][j]<Allocation[i][j])
				swap(Max[i][j],Allocation[i][j]);
            Need[i][j] = Max[i][j] - Allocation[i][j];  //还需要的该类资源
        }
    }
}
//有关安全性算法的数组初始化
void initSafe()
{
    for(int i=1;i<=resourceNum;i++)
    {
        Work[i] = Available[i];
    }
    memset(Finish, false, sizeof(Finish));
}

void test(int i) //尝试将资源分配给第i个进程
{
    for(int j=1;j<=resourceNum;j++)
    {
        Available[j] = Available[j]-Request[j];
        Allocation[i][j] = Allocation[i][j]+Request[j];
        Need[i][j] = Need[i][j]-Request[j];
    }
}

void reTest(int i)//撤销在第i个进程上所做的尝试
{
    for (int j = 1; j <= resourceNum; j++)
    {
        Available[j] = Available[j]+Request[j];
        Allocation[i][j] = Allocation[i][j]-Request[j];
        Need[i][j] = Need[i][j]+Request[j];
    }
}

//安全性算法;检测当前系统是否处于安全状态
bool safe()
{
    int i,j,k=1,m,apply;
	initSafe();  //对Work和Finish的初始化
	//求安全序列 
	for(i=1;i<=proNum;i++) //i代表的是进程, j代表的是资源
    {   
		apply=0;
		for(j=1;j<=resourceNum;j++) //遍历每一类资源
        {
			if(Finish[i]==false && Need[i][j]<=Work[j])
			{   
				apply++;
			}
		}
        //直到每类资源尚需数都小于系统可利用资源数才可分配
        if(apply==resourceNum)  //可以分配啦
        {  
            for(m=1;m<=resourceNum;m++) //遍历每一类资源,回收资源
                Work[m]=Work[m]+Allocation[i][m];//更改当前可分配资源(i进程已经拥有的m类资源的数量)
            Finish[i]=true; //第i个进程完成
            Security[k++]=proName[i];
            i=0; //保证每次查询均从第一个进程开始		
        }
	}
	
	for(i=1;i<=proNum;i++)
    {
		if(Finish[i]==false)  //该调度下,无法执行完所有的进程
        {
			printf("当前系统不安全!\n");//不成功系统不安全
			return false;
		}
	}
    printf("系统是安全的!\n");//如果安全,输出成功
    printf("存在一个安全序列:");
	for(i=1;i<=proNum;i++){//输出运行进程数组
		cout << Security[i];
		if(i<proNum) 
			printf("->");
	}
	printf("\n");
	printf("资源分配完毕!");
	return true;
}


//展示调度情况的算法
void display()
{
    int i,j;
	printf("*************************************************************\n");
	printf("系统目前可用的资源[Available]:\n");
    printf("资源名称    ");
	for(i=1;i<=resourceNum;i++)  //输出资源名称
        cout << resourceName[i] << "   ";
	printf("\n");
    printf("资源剩余量");
	for(i=1;i<=resourceNum;i++)  //输出资源剩余量
		printf("%4d ",Available[i]);
        // cout << Available[i] << "   ";
	printf("\n");
	printf("系统当前的资源分配情况如下:\n");
	printf("              Max   	   Allocation       Need\n");
	printf("进程名   ");
	//输出与进程名同行的资源名,Max、Allocation、Need下分别对应 
	for(j=0;j<3;j++){
		for(i=1;i<=resourceNum;i++)
			cout << resourceName[i] << "   ";
		printf(" ");
	}
	printf("\n");
	//输出每个进程的Max、Allocation、Need 
	for(i=1;i<=proNum;i++){
		cout << proName[i] << "     ";
	    for(j=1; j<=resourceNum;j++) 
			printf("  %d  ",Max[i][j]);
		printf(" "); 
		for(j=1;j<=resourceNum;j++)
			printf("  %d  ",Allocation[i][j]);
		printf(" "); 
		for(j=1;j<=resourceNum;j++)
			printf("  %d  ",Need[i][j]);
		printf("\n");

    }
}
void bank()
{
    bool flag = true;//标志变量,判断能否进入银行家算法的下一步 
	int i,j;
	printf("请输入请求分配资源的进程号:"); 
    cin >> i;//输入须申请资源的进程号
	printf("请输入进程P%d要申请的资源个数:\n",i);
	for(j=1;j<=resourceNum;j++)
	{
		cout << resourceName[j] << ":";
        cin >> Request[j];  //需要申请的资源数
	}
	//判断银行家算法的前两条件是否成立 
    for (j=1; j<=resourceNum;j++)
	{
		if(Request[j]>Need[i][j])//判断申请是否大于需求,若大于则出错
		{ 
			printf("进程P%d申请的资源大于它需要的资源",i);
			printf("分配不合理,不予分配!\n");
			flag = false;
			break;
		}
		else 
		{
            if(Request[j]>Available[j])//判断申请是否大于当前可分配资源,若大于则出错
			{                         
				printf("进程%d申请的资源大于系统现在可利用的资源",i);
				printf("\n");
				printf("系统尚无足够资源,不予分配!\n");
				flag = false;
				break;
			}
		}
    }
    //前两个条件成立,试分配资源,寻找安全序列 
    if(flag) {
		test(i); //根据进程需求量,试分配资源 
		display(); //根据进程需求量,显示试分配后的资源量 
		if(!safe()) //寻找安全序列,如果不安全要进行资源的撤销
		{
			reTest(i);
			cout << "进行资源的回退!" << endl;
			display();
		}
    }

}

int main()
{
    char isContinue;
	cout << "请输入资源的种类数目:";
    cin >> resourceNum;
    cout << "请输入进程的数目:";
    cin >> proNum;
    //1-初始化资源信息(构造Available,创建随机数据)
    initResources();
	cout << "初始化资源信息完毕!" << endl;
    //2-初始化进程相关数组
    initPro();
	cout << "初始化进程相关数据完毕!" << endl;
    //3-展示数据
    display();
    //4-判断当前时刻系统是否处于安全状态
    if(!safe()) exit(0); //如果不是安全状态直接退出
    //3-开始银行家算法分配资源
	cout << "是否进行银行家算法进行资源分配(y/n)?" ;
	cin >> isContinue;
	while(isContinue=='y')
	{
		bank();
		cout << "是否继续进行银行家算法进行资源分配(y/n)?" ;
		cin >> isContinue;
	}
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值