编程语言
首页 > 编程语言> > 操作系统实验---银行家算法(数据随机生成)

操作系统实验---银行家算法(数据随机生成)

作者:互联网

一、 实验目的
1、了解什么是操作系统安全状态和不安全状态;
2、了解如何避免系统死锁;
3、理解银行家算法是一种最有代表性的避免死锁的算法,掌握其实现原理及实现过程。

二、 实验内容
根据银行家算法的基本思想,编写和调试一个实现动态资源分配的模拟程序,并能够有效避免死锁的发生。

三、 实验原理
进程申请资源时,系统通过一定的算法判断本次申请是否不可能产生死锁(处于安全状态)。若可能产生死锁(处于不安全状态),则暂不进行本次资源分配,以避免死锁。算法有著名的银行家算法。
1、什么是系统的安全状态和不安全状态?
所谓安全状态,是指如果系统中存在某种进程序列<P1,P2,…,Pn>,系统按该序列为每个进程分配其所需要的资源,直至最大需求,则最终能使每个进程都可顺利完成,称该进程序列<P1,P2,…,Pn,>为安全序列。
如果不存在这样的安全序列,则称系统处于不安全状态。
2、银行家算法
把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金。

操作系统按照银行家制定的规则设计的银行家算法为:
(1)进程首次申请资源的分配:如果系统现存资源可以满足该进程的最大需求量,则按当前的申请量分配资源,否则推迟分配。
(2)进程在执行中继续申请资源的分配:若该进程已占用的资源与本次申请的资源之和不超过对资源的最大需求量,且现存资源能满足该进程尚需的最大资源量,则按当前申请量分配资源,否则推迟分配。
(3)至少一个进程能完成:在任何时刻保证至少有一个进程能得到所需的全部资源而执行到结束。
银行家算法通过动态地检测系统中资源分配情况和进程对资源的需求情况来决定如何分配资源,并能在确保系统处于安全状态时才把资源分配给申请者,从而避免系统发生死锁。

四.算法流程图

在这里插入图片描述
在这里插入图片描述

五.实验用到的数据结构及函数
数据结构:
n:进程数,随机生成若干个个进程(为了便于观察,限制随机在3-6个);
m:资源总类数随机生成(同样为了方便观察,限制在3-6个);
char NAME[n] :各个资源的名称,手动输入
Max[n][m]:每个进程每种资源的最大需求量,随机赋值
allocation[n][m]:每个进程每种资源已经分配的资源量,随机赋值
need[n][m]:每个进程每种资源还需要请求的总量,由max和allocation算出
Request[n][m]:每个进程每种资源的请求量,随机生成
Work[m]:工作向量,即可向正在运行的进程分配的资源量
bool Finish[n]:进程是否执行结束
available[m]:可利用资源向量,随机赋值
security[n]:安全监测记录进程完成的顺序

函数:
Init():初始化,随机生成资源总数及各个资源初始数量,以及随机生成进程总数和各个进程的最大资源需求量和以及分配的各资源量
showdata():输出当前各个进程的资源情况
printspace():空格输出,在showdata输出数据时使用,为了界面美观
Safe():判断系统是否处于安全状态
Test(int i):尝试给进程i分配资源
Retest(int i):与test相反,还原分配前的资源情况
Banker():银行家算法核心部分

六:银行家算法代码

因为我是在vs上编写的程序再拿到linux虚拟机那边去运行的,所以主体采用的是c++编写,输出上为了方便有些地方使用了c的输出;所以保存的是cpp文件,到虚拟机那边编译时指令用g++(.c文件编译用gcc);

#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<stdbool.h>
#include<iostream>
#include<iomanip>
using namespace std;
char NAME[100] = { 0 };//资源的名称
int MAX[100][100] = { 0 };//最大需求矩阵
int Allocation[100][100] = { 0 };//系统已分配矩阵
int need[100][100] = { 0 };//还需要资源矩阵
int Available[100] = { 0 };//可用资源矩阵
int request[100] = { 0 };//请求资源向量
int work[100] = { 0 };//存放系统可提供资源量
bool finish[100] = { false };//标记系统是否有足够的资源分配给各个进程
int security[100] = { 0 };//存放安全序列

int N = 100;//进程的最大数
int M = 100;//资源的最大数

/********初始化数据:随机生成进程数量、资源种类、各种资源可利用数量、
各进程对资源最大需求量、各进程的资源已分配数量等。********/

void init() {
	int i, j, n, m;
	char name;
	bool flag;
	srand((unsigned)time(NULL));
	m = rand() % 4 + 3;
	M = m;
	printf("随机生成资源总数为:%d\n", m);
	printf("请输入各个资源的名称:\n");
	for (i = 0; i < m; i++) {
		printf("请输入资源%d的名称: ", i);
		cin >> name;
		NAME[i] = name;
		int number;
		number = rand() % 40 + 20;
		printf("随机生成该资源的初始数量为%d\n", number);
		Available[i] = number;
	}
	n = rand() % 4 + 3;
	N = n;
	printf("*随机生成进程总数为:%d\n", n);
	printf("*随机生成各进程最大资源需求量及各进程已经分配的资源量\n");
	for (i = 0; i < N; i++) {
		for (j = 0; j < M; j++) {
			MAX[i][j] = rand() % 5 + 5;
			while (MAX[i][j] > Available[j])//不符合规则,重新随机生成
				MAX[i][j] = rand() % 5 + 5;
		}
	}
	for (i = 0; i < N; i++) {
		for (j = 0; j < M; j++) {
			Allocation[i][j] = rand() % 10;
			while (Allocation[i][j] > MAX[i][j])//不符合规则,重新随机生成
				Allocation[i][j] = rand() % 10;
			need[i][j] = MAX[i][j] - Allocation[i][j];
			Available[j] -= Allocation[i][j];
		}
	}

	printf("初始化完成\n");
}

/********空格输出函数,为了下面输出美观********/
void printspace() {
	if (M == 3) printf("             ");
	else if (M == 4) printf("          ");
	else if (M == 5) printf("        ");
	else printf("      ");
}

/********显示资源分配矩阵********/
void showdata() {
	int i, j;
	printf("*************************************************************\n");
	printf("系统目前可用资源【Available】:\n");
	for (i = 0; i < M; i++)
		printf("%c   ", NAME[i]);
	printf("\n");
	for (j = 0; j < M; j++)
		printf("%d  ", Available[j]);
	printf("\n\n");
	printf("系统当前资源分配情况如下:\n");
	cout << setw(12) << "MAX" << setw(24) << "Allocation" << setw(16) << "need\n";
	printf("进程名  ");
	//输出与进程名同行的资源名,Max、Allocation、Need下分别对应
	for (i = 0; i < 3; i++) {
		for (j = 0; j < M; j++)
			printf("%c ", NAME[j]);
		printspace();
	}
	printf("\n");
	for (i = 0; i < N; i++) {
		printf(" p%d     ", i);
		for (j = 0; j < M; j++) {
			printf("%d ", MAX[i][j]);
		}
		printspace();
		for (j = 0; j < M; j++) {
			printf("%d ", Allocation[i][j]);
		}
		printspace();
		for (j = 0; j < M; j++) {
			printf("%d ", need[i][j]);
		}
		printf("\n");
	}
}

/********尝试分配资源给进程i********/
int test(int i) {
	for (int j = 0; j < M; j++) {
		Available[j] -= request[j];
		Allocation[i][j] += request[j];
		need[i][j] -= request[j];
	}
	return true;
}

/********试探性分配资源作废********/
int retest(int i) {
	for (int j = 0; j < M; j++) {
		Available[j] += request[j];
		Allocation[i][j] -= request[j];
		need[i][j] += request[j];
	}
	return true;
}


/********安全性算法********/
int safe() {
	int i, j, k = 0, m, apply;
	for (j = 0; j < M; j++)
		work[j] = Available[j];//初始化work
	for (i = 0; i < N; i++)
		finish[i] = false;//初始化Finish 
	//求安全序列
	for (i = 0; i < N; i++) {
		apply = 0;
		for (j = 0; j < M; j++) {
			if (finish[i] == false && need[i][j] <= work[j]) {
				apply++;//直到每类资源尚需数都小于系统可利用资源数才可分配
				if (apply == M) {
					for (m = 0; m < M; m++)
						work[m] += Allocation[i][m];//更改当前可分配资源
					finish[i] = true;
					security[k++] = i;
					i = -1;//保证每次查询均从第一个进程开始
				}
			}
		}
	}
	for (i = 0; i < N; i++) {
		if (finish[i] == false) {
			printf("系统不安全\n");//不成功系统不安全
			return false;
		}
	}
	printf("系统是安全的:\n");//如果安全,输出成功
	printf("存在一个安全序列:");
	for (i = 0; i < N; i++) {//输出安全序列
		printf("p%d", security[i]);
		if (i < N - 1)
			printf("->");
	}
	printf("\n");
	return true;
}

void bank()
{
	int flag = true;//标志变量,判断能否进入银行家算法的下一步 
	int i, j;

	printf("请输入请求分配资源的进程号(0-%d):", N - 1);
	cin >> i;

	printf("随机生成进程P%d要申请的各个资源个数为:\n", i);
	for (j = 0; j < M; j++)
	{
		request[j] = rand() % 6;
		printf("%d  ", request[j]);
	}
	printf("\n");

	//判断银行家算法的前两条件是否成立 
	for (j = 0; j < M; 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); //根据进程需求量,试分配资源 
		showdata(); //根据进程需求量,显示试分配后的资源量 
		if (!safe()) //寻找安全序列
		{
			retest(i);
			showdata();
		}
	}
}


int main() {
	char choice;
	printf("\t---------------------------------------------------\n");
	printf("\t||                                               ||\n");
	printf("\t||                  银行家算法                   ||\n");
	printf("\t||                                               ||\n");
	printf("\t---------------------------------------------------\n\n");
	printf("\t---------------------初始化资源--------------------\n");
	init();//初始化数据
	showdata();//显示各种资源
	//用银行家算法判定系统当前时刻是否安全,不安全就不再继续分配资源 
	if (!safe()) exit(0);
	while (1) {
		printf("*************************************************************\n");
		printf("\n");
		printf("\n");
		printf("\t-------------------银行家算法演示------------------\n");
		printf("                     q:查看当前资源分配情况   \n");
		printf("                     r:请求分配资源           \n");
		printf("                     e::退出                  \n");
		printf("\t---------------------------------------------------\n");
		printf("请选择:");
		cin >> choice;
		switch (choice)
		{
		case 'q':
			showdata(); break;
		case 'r':
			bank(); break;
		case 'e':
			exit(0);
		default: printf("请正确选择!\n"); break;
		}
	}
}

七:运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

就酱,看完记得点赞哦!!!!!

标签:操作系统,++,---,int,算法,printf,进程,资源,银行家
来源: https://blog.csdn.net/gdnlnsjd/article/details/117378613