IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 用C语言或C++编写一个简单的银行家算法模拟程序 -> 正文阅读

[C++知识库]用C语言或C++编写一个简单的银行家算法模拟程序

1.问题描述

银行家算法是操作系统中避免死锁的典型算法。用C语言或C++编写一个简单的银行家算法模拟程序,实现多个进程争用系统临界资源时的分配过程。要求程序实现:
1.当一进程请求一组资源时,先确定是否有足够的资源分配给该进程。如果有,再进一步计算在将这些资源分配给进程后,系统是否处于不安全状态。如果安全,显示安全序列,将资源分配给该进程,否则进程等待。
2.可以显示当前时刻各进程的的资源分配情况。

2.问题分析

①相关概念
死锁:指多个并发进程彼此等待对方所拥有的资源,且这些并发进程在得到对方的资源之前不会释放自己所拥有的资源,从而使得各进程不能继续向前推前。
在这里插入图片描述

避免死锁(动态预防):允许进程动态地申请资源,但系统在进行资源分配之前,应先计算这次资源分配的安全性。若这次分配不会导致系统进入不安全状态,则将资源分配给进程;否则,令进程等待
银行家算法是一种用来避免操作系统死锁出现的有效算法。为实现银行家算法,系统必须设置若干数据结构,同时要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全状态:是指系统能按某种进程顺序(P1,P2,…,Pn) (称<P1,P2,…,Pn>序列为安全序列),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。

银行家算法中的数据结构:

可利用资源向量 Available[m]
最大需求矩阵 Max[n][m]
分配矩阵 Allocation[n][m]
需求矩阵 Need[n][m]
进程Pi的请求向量 Request[m]
其中, Need[i,j]=Max[i,j]-Allocation[i,j]

银行家算法描述:

(1) If (Requesti[j]≤Need[i,j])(2)else  出错处理。
(2) If (Requesti[j]≤Available[j]),转(3)else  Pi等待。 
(3) 系统试着把资源分配给进程Pi,即修改下面数据结构中的数值:
	Available[j]= Available[j]-Requesti[j];
	Allocation[i,j]= Allocation[i,j]+Requesti[j];
	Need[i,j]= Need[i,j]-Requesti[j];
(4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
	If(安全)正式将资源分配给进程Pi;
	else  将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

③安全性算法中的数据结构:

Work[m]:工作向量,表示系统可提供给进程继续运行所需的各类资源数目,在执行安全算法开始时,Work=Available
Finish[n]:它表示系统是否有足够的资源分配给进程、使之运行完成。开始时先做Finish[i]=false;当有足够资源分配给进程时,再令Finish[i]=true

安全性算法描述:

(1)从进程集合中找到一个能满足下述条件的进程Pi:
	(Finish[i]=false && Need[i,j]≤Work[j])
	如果找到,转(2),否则,转(3)(2)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
	Work[j]= Work[j]+Allocation[i,j];
	Finish[i]= true;(1);
(3) If(所有进程的Finish[i]= true)系统处于安全状态;
    else  系统处于不安全状态。

3、问题解决

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

#define RESOURCES_MAX 5//系统最多拥有5种资源
#define PROCESS_MAX 5//系统最多拥有的进程数
#define true 1
#define false 0
typedef int bool;

int available[RESOURCES_MAX];//可利用资源向量
int maxRequest[PROCESS_MAX][RESOURCES_MAX];//最大需求矩阵
int allocation[PROCESS_MAX][RESOURCES_MAX];//分配矩阵
int need[PROCESS_MAX][RESOURCES_MAX];//需求矩阵
bool Finish[PROCESS_MAX];
int safeSeries[PROCESS_MAX];//记录安全序列
int request[RESOURCES_MAX];//进程Pi的请求向量Requesti[j]

int resource_num;//输入的资源数量种类数
int process_num;//输入的进程数量
#define name_size 5 //资源名称的字符长度
char resource_name[RESOURCES_MAX][name_size];//记录各资源名称

void showInfo();/*显示系统目前可用的资源*/
bool isSafe();//安全性算法的实现
void showSafe();//安全序列的信息

int main() {
	/**输入,初始化各矩阵**/
	printf("输入资源种类:");
	scanf("%d", &resource_num);//输入的资源种类数
	for (int i = 0; i < resource_num; i++) {//每种资源的数量
		printf("输入资源%d的名称:", i + 1);
		scanf("%s", resource_name[i]);
		printf("输入资源%d的数量:", i + 1);
		scanf("%d", &available[i]); //可利用资源向量available[]

	}
	printf("输入进程的数量:");//输入的进程数
	scanf("%d", &process_num);
	printf("输入各进程的最大需求量(5*3矩阵)[maxRequest]:\n");
	for (int i = 0; i < process_num; i++)
		for (int j = 0; j < resource_num; j++)
			scanf("%d", &maxRequest[i][j]);//最大需求矩阵maxRequest

	printf("输入各进程已经申请的资源量(5*3矩阵)[allocation]:\n");
	for (int i = 0; i < process_num; i++)
		for (int j = 0; j < resource_num; j++)
			scanf("%d", &allocation[i][j]);//已分配矩阵allocation

	/*计算需求矩阵need,need[i,j]=maxRequest[i,j]-allocation[i,j]*/
	for (int i = 0; i < process_num; i++)
		for (int j = 0; j < resource_num; j++)
			need[i][j] = maxRequest[i][j] - allocation[i][j];//需求矩阵need

	/*显示系统目前可用的资源*/
	showInfo();

	/**判断系统是否安全**/
	isSafe();

	while (1) {
		printf("***********************************\n");
		printf("1:分配资源\n2:显示分配情况\n0:离开\n");
		printf("***********************************\n");
		printf("请选择功能号:");
		int choice;
		scanf("%d", &choice);

		if (choice == 0) {//离开
			printf("已离开!\n");
			break;
		}
		if (choice == 2) {//显示分配情况
			showInfo();//显示系统目前可用的资源
			continue;
		}
		if (choice == 1) {//分配资源
			int processID;//要求分配的资源进程号
			printf("请输入要求分配的资源进程号(0-4):");
			scanf("%d", &processID);
			printf("请输入进程 %d 申请的资源:\n", processID);
			for (int i = 0; i < resource_num; i++) {
				printf("%s:", resource_name[i]);
				scanf("%d", &request[i]);
			}

			//检查request[i]与该进程的need[][i],available[i]
			for (int i = 0; i < resource_num; i++) {
				if ((request[i] > need[processID][i]) || (request[i] > available[i])) {
					printf("没有足够的资源分配给该进程!\n");
					continue;
				}
			}

			//假设可以分配资源,修改available,allocation,need
			for (int i = 0; i < resource_num; i++) {
				available[i] = available[i] - request[i];
				allocation[processID][i] += request[i];
				need[processID][i] -= request[i];
			}

			/**判断系统是否安全**/
			if (isSafe())continue;
			else {//系统不安全,不予分配
				for (int i = 0; i < resource_num; i++) {
					available[i] += request[i];
					allocation[processID][i] -= request[i];
					need[processID][i] += request[i];
				}
			}
		}//if(choice==1)
	}//while
	return 0;
}

void showInfo() {
	/*显示系统目前可用的资源*/
	printf("\n系统目前可用的资源[avaliable]:\n");
	for (int i = 0; i < resource_num; i++) {
		printf("%s\t", resource_name[i]);
	}
	printf("\n");
	for (int i = 0; i < resource_num; i++) {
		printf("%d\t", available[i]);
	}
	printf("\n");

	printf("\tMax  Allocation  Need\n");
	printf("进程");
	for (int i = 0; i < 3; i++) {
		printf("\t");
		for (int i = 0; i < resource_num; i++) {
			printf("%s ", resource_name[i]);
		}
	}
	printf("\n");
	for (int i = 0; i < process_num; i++) {
		printf("%d\t", i);//进程i
		for (int j = 0; j < resource_num; j++) {
			printf("%d ", maxRequest[i][j]);
		}
		printf("\t");
		for (int j = 0; j < resource_num; j++) {
			printf("%d ", allocation[i][j]);
		}
		printf("\t");
		for (int j = 0; j < resource_num; j++) {
			printf("%d ", need[i][j]);
		}
		printf("\n");
	}
}

/*安全性算法的实现*/
bool isSafe() {
	int work[RESOURCES_MAX];//工作向量,表示系统可提供给进程继续运行所需的各类资源数目
	for (int i = 0; i < resource_num; i++)//在执行安全算法开始时,Work=Available
		work[i] = available[i];

	for (int i = 0; i < process_num; i++)//初始时未分配够资源
		Finish[i] = false;

	int safeIndex = 0;//安全序列下标
	int tempIndex = 0;//记录上次 从进程0遍历完所有进程时,安全序列的下标
	int i = 0;//进程下标
	while (1) {
		if (Finish[i] == false) {//进程i还未加入安全序列
			int j = 0;
			for (j = 0; j < resource_num; j++) {
				if (need[i][j] > work[j])//need:5*3 work 1*3
					break;
			}
			if (j == resource_num) {// 每个need[i][j]<=work[j],可以给进程i分配资源
				Finish[i] = true;
				safeSeries[safeIndex] = i;//进程i放入安全序列
				safeIndex++;
				for (int k = 0; k < resource_num; k++)
					work[k] = work[k] + allocation[i][k];
			}
		}

		if (safeIndex == process_num) {//所有进程的Finish[i]=true,存在安全序列safeSeries[],系统处于安全状态
			showSafe();//安全序列信息
			printf("系统是安全的!\n");
			for (int i = 0; i < process_num; i++) {
				printf("%d", safeSeries[i]);
				if (i != (process_num - 1))printf("->");
			}
			printf("\n");
			return true;
		}
		i++;//下一个进程
		if (i == process_num) {//已经从头遍历所有进程
			if (tempIndex == safeIndex) {//安全序列没有新增进程
				printf("系统不存在安全序列,不予分配!\n");
				return false;
			}
			else {//安全序列新增进程
				tempIndex = safeIndex;
				i = i % process_num;//下一个进程
			}
		}
	}//while(1)
}

void showSafe() {
	int work[RESOURCES_MAX];//工作向量
	for (int i = 0; i < resource_num; i++)//开始时,Work=Available
		work[i] = available[i];
	printf("\tWork  Allocation  Need\n");
	printf("进程");
	for (int i = 0; i < 3; i++) {
		printf("\t");
		for (int i = 0; i < resource_num; i++)
			printf("%s ", resource_name[i]);
	}
	printf("\n");
	int processID;
	for (int i = 0; i < process_num; i++) {
		processID = safeSeries[i];
		printf("%d\t", processID);//进程safeSeries[i]
		for (int j = 0; j < resource_num; j++)
			printf("%d ", work[j]);
		printf("\t");
		for (int j = 0; j < resource_num; j++)
			printf("%d ", allocation[processID][j]);
		printf("\t");
		for (int j = 0; j < resource_num; j++)
			printf("%d ", need[processID][j]);
		printf("\n");
		for (int j = 0; j < resource_num; j++)
			work[j] += allocation[processID][j];//释放出分配给它的资源
	}
}

测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-04 13:12:48  更:2021-12-04 13:14:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:48:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码