银行家算法的C++模拟

实验五 银行家算法

实验题目:银行家算法的模拟

提示1

  • 我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源。
  • 当进程在执行中申请资源时,先检查该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过,则再测试系统现存的资源能否满足该进程申请的资源量,若能满足则按当前的申请量分配资源,否则也要拒绝分配。

提示2

  • 安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态
    一定是没有死锁发生。
  • 不安全状态:不存在一个安全序列。不安全状态一定导致死锁。
  • 安全序列:一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。

提示3

request为进程p[i]的请求向量,如果request[j]=K,表示进程p[i]需要KR[j]资源。当系统发出请求后,系统按下述步骤开始检查:
1)如果request[j]<=need[i][j],转向步骤2;否则报告出错,申请的资源已经大于它需要的最大值。
2)如果request[j]<=available[j],转向步骤3;否则报告出错,尚无足够的资源。
3)系统试探着把资源分配给p[i],并修改下列数据结构中的值:

available[j]=available[j]-request[j]
allocation[i][j]=allocation[i][j]+request[j]
need[i][j]=need[i][j]request[j]

4)系统进行安全性算法,检查此次分配后,系统是否还处于安全状态,若安全,把资源分配给进程p[i];否则,恢复原来的资源分配状态,让进程p[i]等待

提示4

安全性算法:
int work[RESOURCE_NUMBER];
bool finish[PROCESS_NUMBER];

  1. Work=Available;
    Finish=false;
  2. 寻找满足条件的i:
    A、Finish[i]=false;
    B、Need[i]≤Work;
    如果不存在,则转4;
  3. Work:=Work+Allocation[i]; Finish[i]:=true; 转2;
  4. 若对所有i,Finish[i]=true,则系统处于安全状态,否则处于不安全状态。

提示5(银行家算法的程序流程图)

image-20211128214359127

程序中使用的数据结构及符号说明

  • 数组(数据结构),保存进程、资源的各类信息以及安全序列
string resource[1000];		//资源名
int available[1000];		//各资源的刚开始的可用数量
int work[1000];				//工作时各资源的可用数量
int Max[1000][1000];		//进程的最大所需资源
int allocation[1000][1000]; //进程的已分配资源
int need[1000][1000];		//进程当前需要的资源
bool Finish[1000];			//进程是否完成
int request[1000];			//请求资源
int safe[1000];	//安全序列
  • 整型变量
int processNum = 0;			//进程数
int resourceNum = 0;		//资源类型数
  • 函数说明:
    • void Init():输入信息。
    • void display():显示当前所有进程分配状态。
    • bool isSafe():安全性检查算法,安全返回true,不安全返回false。

源程序并附上注释

#include<iostream>
#include<iomanip>

using namespace std;

int processNum = 0;			//进程数
int resourceNum = 0;		//资源类型数
string resource[1000];		//资源名
int available[1000];		//各资源的刚开始的可用数量
int work[1000];				//工作时各资源的可用数量
int Max[1000][1000];		//进程的最大所需资源
int allocation[1000][1000]; //进程的已分配资源
int need[1000][1000];		//进程当前需要的资源
bool Finish[1000];			//进程是否完成
int request[1000];			//请求资源
int safe[1000];	//安全序列

//初始化
void Init()
{
	int i, j;
	cout << "请输入进程数量:";
	cin >> processNum;
	cout << "请输入资源类型数量:";
	cin >> resourceNum;
	cout << "请依次输入各资源的名称(不超过6个字符)和可用数目:" << endl;
	cout << "例:A 3 B 3 C 2" << endl;
	for (i = 0; i < resourceNum; i++)
	{
		cin >> resource[i] >> available[i];
	}
	//最大需求的矩阵Max:
	cout << "请输入最大需求的矩阵:" << endl;
	cout << "(进程顺序为从0到processNum,资源顺序为:";
	for (j = 0; j < resourceNum; j++)
	{
		cout << resource[j] << " ";
	}
	cout << ")" << endl;
	for (i = 0; i < processNum; i++)
	{
		for (j = 0; j < resourceNum; j++)
		{
			cin >> Max[i][j];
		}
	}
	//分配矩阵allocation:
	cout << "请输入当前分配各资源类型数量的矩阵"<<endl;
	cout << "(进程顺序为1-processNum,资源顺序为:";
	for (j = 0; j < resourceNum; j++)
	{
		cout << resource[j]<<" ";
	}
	cout << ")" << endl;
	for (i = 0; i < processNum; i++)
	{
		for (j = 0; j < resourceNum; j++)
		{
			cin >> allocation[i][j];
		}
	}
	//根据Max和allocation算出需求矩阵need:
	for (i = 0; i < processNum; i++)
	{
		for (j = 0; j < resourceNum; j++)
		{
			need[i][j] = Max[i][j] - allocation[i][j];
		}
	}
}
//显示当前所有进程分配状态
void showInfo()
{
	int i, j;
	int len = 8 * resourceNum;
	cout << "当前系统状态如下:" << endl;
	//第1行:根据资源数的不同,居左输出
	cout << "        ";
	cout << left << setw(len) << "Max";
	cout << left << setw(len) << "Allocation";
	cout << left << setw(len) << "Need";
	cout << left << setw(len) << "Available";
	cout << left << endl;
	//第2行:资源名
	cout << "        ";
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < resourceNum; j++)
		{
			cout << left << setw(8) << resource[j];
		}
	}
	cout << endl;
	//后面processNum行:各进程的资源情况
	for (i = 0; i < processNum; i++)
	{
		cout << "P" << i<<"      ";
		for (j = 0; j < resourceNum; j++)
		{
			cout << left << setw(8) << Max[i][j] ;
		}
		for (j = 0; j < resourceNum; j++)
		{
			cout << left << setw(8)<< allocation[i][j];
		}
		for (j = 0; j < resourceNum; j++)
		{
			cout << left << setw(8) << need[i][j];
		}
		//第三行输出多一项可用资源数
		if (i == 0)
		{
			for (j = 0; j < resourceNum; j++)
			{
				cout << left << setw(8) << available[j];
			}
		}
		cout << endl;
	}
}
//安全性检查算法
bool isSafe()
{
	int i, j, k;
	int round= 0; //循环轮数
	int FinishNum = 0; //已完成的进程数
	//work初始化
	for (i = 0; i < resourceNum; i++)
	{
		work[i] = available[i];
	}
	//Finish初始化
	for (i = 0; i < processNum; i++)
	{
		Finish[i] = false;
	}
	i = 0;
	int temp = 0;
	while (FinishNum < processNum) //有进程未完成
	{
		j = 0; //每次检查前,j需要初始化为0
		//当前进程i是否满足Finish==false并且need<work
		if (Finish[i] == false)
		{
			for (j = 0; j < resourceNum; j++)
			{
				if (need[i][j] > work[j])
				{
					break;
				}
			}
		}
		//满足上面的条件则进行第3步:分配并释放资源,完成进程,记录于安全序列
		if (j == resourceNum)
		{
			Finish[i] = true;
			for (k = 0; k < resourceNum; k++)
			{
				work[k] += allocation[i][k];
			}
			//输出当前可用资源数
			cout << "进程" << i << "执行完成,释放资源。" << "当前可用资源数如下:" << endl;
			for (k = 0; k < resourceNum; k++)
			{
				cout << left << setw(8) << resource[k];
			}
			cout << endl;
			for (k = 0; k < resourceNum; k++)
			{
				cout << left << setw(8) << work[k];
			}
			cout << endl;
			safe[FinishNum] = i;
			FinishNum++;
		}
		i++; //检查下一个进程
		if (i >= processNum) //循环了一轮
		{
			i %= processNum;
			if (temp == FinishNum && round > 0) //再次循环后进程完成数没有变化,则没有可以完成的进程了
				break;
			round++;
			temp = FinishNum; //记录本次循环的FinishNum
		}
	}
	if (FinishNum == processNum)
	{
		cout << "系统安全,安全序列为:";
		for (i = 0; i < processNum; i++)
		{
			cout << "P" << safe[i] << " ";
		}
		cout << endl;
		return true;
	}
	else
	{
		cout << "剩余进程无法完成,系统不安全!"<<endl;
		return false;
	}
}
//主函数
int main()
{
	int i, j;
	Init();
	showInfo();
	//初始化后检查安全性,若不安全则程序结束。
	cout << "开始检查系统安全性:" << endl;
	if (!isSafe())
	{
		cout << "程序结束" << endl;
		return 0;
	}
	while (true)
	{
		cout << "---------------------------------------------------------" << endl;
		cout << "请输入要分配的进程:";
		cin >> i;
		cout << "请输入要分配给进程P" << i << "的资源:" << endl;
		cout<< "资源顺序为:";
		for (j = 0; j < resourceNum; j++)
		{
			cout << resource[j] << " ";
		}
		cout << endl;
		for (j = 0; j < resourceNum; j++)
		{
			cin >> request[j];
		}
		//按步骤开始检查
		for (j = 0; j < resourceNum; j++)
		{
			if (request[j] <= need[i][j])
				continue;
			else
			{
				cout << "错误!申请的资源已经大于它需要的最大值" << endl;
				break;
			}
		}
		if (j == resourceNum)
		{
			for (j = 0; j < resourceNum; j++)
			{
				if (request[j] <= available[j])
					continue;
				else
				{
					cout << "错误!尚无足够的资源" << endl;
					break;
				}
			}
		}
		if (j == resourceNum)
		{
			//尝试分配,修改数据结构的值
			for (j = 0; j < resourceNum; j++)
			{
				available[j] -= request[j];
				allocation[i][j] += request[j];
				need[i][j] -= request[j];
			}
			cout << "开始检查系统安全性:" << endl;
			if (isSafe())
			{
				cout << "分配成功!\n";
				showInfo();
			}
			else
			{
				//分配失败,则恢复数据结构的值
				for (j = 0; j < resourceNum; j++)
				{
					available[j] += request[j];
					allocation[i][j] -= request[j];
					need[i][j] += request[j];
				}
				cout << "分配失败!\n";
				showInfo();
			}
		}
	}
}

程序运行时的初值和运行结果

初值

  1. 初始化

image-20211128215453437

  1. 三次申请资源

    image-20211128215606893

    image-20211128215732054

    image-20211128215819214

运行结果

image-20211128221739018

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qU4P1hBF-1638676609613)(第五次实验 银行家算法/image-20211128221042945.png)]

image-20211128221106632

image-20211128221952657

思考题

设计本实验时,就尽可能的将设计人性化和考虑全面。如:能不断地进行资源分配;能修改资源的初始状态;提示信息就能充分反映算法过程等。

  • 不断进行资源分配、提示信息就能充分反映算法过程等,在前文的代码中已经实现。为了能够在中途修改资源的状态,增加自定义函数change()置于检查安全性的算法isSafe()中,改变的部分如下:

    //修改资源分配的函数
    bool change()
    {
    	bool flag = false;
    	int i,j;
    	char ch;
    	while (1)
    	{
    		cout << "是否要改变资源分配状态(Y:是,N:否):" << endl;
    		cin >> ch;
    		if (ch == 'Y')
    		{
    			flag = true;
    		}
    		else
    		{
    			break;
    		}
    		cout << "请选择需要改变的进程:" << endl;
    		cin >> i;
    		cout << "请输入它最新的最大需求矩阵Max:" << endl;
    		for (j = 0; j < resourceNum; j++)
    		{
    			cin >> Max[i][j];
    		}
    		cout << "请输入它最新的分配矩阵allocation:" << endl;
    		for (j = 0; j < resourceNum; j++)
    		{
    			cin >> allocation[i][j];
    		}
    		//更新需求矩阵
    		for (j = 0; j < resourceNum; j++)
    		{
    			need[i][j] = Max[i][j] - allocation[i][j];
    		}
    	}
    	if (flag)
    	{
    		cout << "请依次输入各资源的名称(不超过6个字符)和可用数目:" << endl;
    		cout << "例:A 3 B 3 C 2" << endl;
    		for (i = 0; i < resourceNum; i++)
    		{
    			cin >> resource[i] >> available[i];
    		}
    	}
    	return flag;
    }
    
    //安全性检查算法
    bool isSafe()
    {
    	int i, j, k;
    	int round= 0; //循环轮数
    	int FinishNum = 0; //已完成的进程数
    	//work初始化
    	for (i = 0; i < resourceNum; i++)
    	{
    		work[i] = available[i];
    	}
    	//Finish初始化
    	for (i = 0; i < processNum; i++)
    	{
    		Finish[i] = false;
    	}
    	i = 0;
    	int temp = 0;
    	while (FinishNum < processNum) //有进程未完成
    	{
    		j = 0; //每次检查前,j需要初始化为0
    		//当前进程i是否满足Finish==false并且need<work
    		if (Finish[i] == false)
    		{
    			for (j = 0; j < resourceNum; j++)
    			{
    				if (need[i][j] > work[j])
    				{
    					break;
    				}
    			}
    		}
    		//满足上面的条件则进行第3步:分配并释放资源,完成进程,记录于安全序列
    		if (j == resourceNum)
    		{
    			Finish[i] = true;
    			for (k = 0; k < resourceNum; k++)
    			{
    				work[k] += allocation[i][k];
    			}
    			//输出当前可用资源数
    			cout << "进程" << i << "执行完成,释放资源。" << "当前可用资源数如下:" << endl;
    			for (k = 0; k < resourceNum; k++)
    			{
    				cout << left << setw(8) << resource[k];
    			}
    			cout << endl;
    			for (k = 0; k < resourceNum; k++)
    			{
    				cout << left << setw(8) << work[k];
    			}
    			cout << endl;
    			safe[FinishNum] = i;
    			FinishNum++;
    		}
    		i++; //检查下一个进程
    		if (i >= processNum) //循环了一轮
    		{
    			i %= processNum;
    			if (temp == FinishNum && round > 0) //再次循环后进程完成数没有变化,则没有可以完成的进程了
    				break;
    			round++;
    			temp = FinishNum; //记录本次循环的FinishNum
    		}
    	}
    	if (FinishNum == processNum)
    	{
    		cout << "系统安全,安全序列为:";
    		for (i = 0; i < processNum; i++)
    		{
    			cout << "P" << safe[i] << " ";
    		}
    		cout << endl;
    		return true;
    	}
    	else
    	{
    		cout << "剩余进程无法完成,系统不安全!"<<endl;
    		if (change())
    		{
    			cout << "将重新进行检查系统安全性:";
                display();
    			return isSafe();
    		}
    		else
    			return false;
    	}
    }
    

运行结果

image-20211204171631704

image-20211204171738177

实验总结和心得

  • 设计本实验,如何设计得更人性化,考虑得更全面是值得注意的。要用打印的提示信息尽量美观且反映算法过程,这使得我和cout纠缠不清了一段时间。整个实验过程中,我也是在不断地发现问题、观察调试、解决问题,好在最后效果不错。

  • 整个实验逻辑比较清晰,具体流程在实验指导书中都有说明。将算法思想转化为实际代码去实现,让我对银行家算法的算法思想和设计有了更加深刻的了解,较好地锻炼了我的逻辑思维和编程能力。

  • 4
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
银行家算法是一种避免死锁的算法,用于分配有限的资源给进程。它是由艾德加·达卡(Edsger W. Dijkstra)在1965年提出的。 以下是一个简单的操作系统设计银行家算法模拟实现的示例: 1. 初始化 首先,需要确定系统中所有进程需要的资源总量,以及每个进程当前已经占有的资源量。这些信息可以存储在一个维数组中,如下所示: ``` int Allocation[n][m]; // 已经分配给进程的资源数量 int Max[n][m]; // 进程需要的最大资源数量 int Need[n][m]; // 进程还需要的资源数量 int Available[m]; // 系统当前可用的资源数量 ``` 其中,n 表示进程数,m 表示资源类型数。 2. 检查请求 当一个进程请求资源时,需要检查该进程是否能够获得请求的资源。首先,需要检查进程请求的资源量是否小于等于该进程还需要的资源量。如果不是,说明该进程已经获得了所有它需要的资源,不能再请求更多资源了。 接下来,需要检查系统当前是否有足够的资源分配给该进程。具体来说,需要检查该进程请求的资源量是否小于等于系统当前可用的资源量。如果不是,说明系统没有足够的资源分配给该进程。 如果上述两个条件都满足,说明该进程可以获得请求的资源。可以暂时将资源分配给该进程,然后运行安全性算法检查该分配是否安全。 3. 安全性算法 安全性算法用于检查当前的资源分配是否安全。简单来说,如果系统当前的资源分配可以避免死锁,那么该分配就是安全的。 安全性算法的具体实现需要用到银行家算法的核心思想:避免剥夺。即,如果一个进程已经获得了一些资源,那么它不能再被剥夺这些资源,否则可能导致死锁。 安全性算法通常采用贪心策略,从当前可用资源中选择一个进程,尝试将资源分配给该进程,然后检查该分配是否安全。如果安全,则将资源分配给该进程,并将该进程从系统中删除。如果不安全,则尝试选择下一个进程。 如果所有进程都被删除,那么该分配就是安全的。否则,该分配是不安全的。 4. 回收资源 当一个进程释放资源时,需要将这些资源回收到系统中,然后运行安全性算法检查是否有其他进程可以获得这些资源。 具体来说,需要将释放的资源数量加到系统当前可用的资源数量中,然后运行安全性算法检查是否有进程可以获得这些资源。 以上就是操作系统设计银行家算法模拟实现的基本流程。要注意的是,实际应用中可能需要考虑更多细节和特殊情况,比如进程优先级、优先级反转、异常处理等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yuhan_2001

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

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

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

打赏作者

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

抵扣说明:

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

余额充值