资源分配----银行家算法

一、 实验目的
模拟实现银行家算法,用银行家算法实现资源分配和安全性检查。通过本次实验,使学生加深对死锁概念的理解和掌握,并培养学生对操作系统课程的兴趣与高级语言设计的能力。

二、 实验内容 1、要求
设计五个进程{P0···P4}共享三类资源{A,B,C}的系统,每一种资源数量为10,5,7。进程可动态的申请和释放资源,系统按各进程的申请动态地分配资源,在T0时刻的资源分配情况如下表:

Name       Max        Allocation       Need       Available
P0        7,5,3       0,1,0       7,4,3        3,3,2
P1        3,2,2       2,0,0       1,2,2
P2        9,0,2       3,0,2       6,0,0
P3        2,2,2       2,1,1       0,1,1
P4        4,3,3       0,0,2       4,3,1

(1) 银行家算法的数据结构
•Resource:一个长度为m向量,表示系统拥有的资源数目。
•Available:一个长度为m向量,表示每类资源的可用数目。
•Max:一个m×n矩阵,定义每个进程的最大资源需求数。
•Allocation:一个m×n矩阵,定义当前分配给每个进程每类资源的数目。
•Need:一个m×n矩阵,表示每个进程还需多少资源。

(2) 实现银行家算法 设:Requesti是进程Pi的请求向量。
当Pi发出资源请求后,系统按如下步骤进行检查:
•如果Request[j] Need[i][j] 则go to 2,否则认为出错。
•如果Request[j] < Available[i][j] 则go to 3,否则表示无足够资源, Pi等待。
•系统进行试探分配,并求该相应数据结构数据
Available:= Available- Requesti
Allocationi:= Allocationi+ Requesti
Needi:= Needi-Requesti
•系统执行安全性算法:安全,把资源分配给Pi,否则, Pi等待。

(3) 实现安全性算法
•设Work 和 Finish是长度分别为m,n的向量
初试值Work =Available ,Finishi = False(所有)
•从进程集合中找到一个能满足下列条件的进程
a. Finishi= False
b. Needi Work 如找到go to 3 否则 go to 4
•当进程Pi 获得资源后,顺利执行,直至完成,并释放分配给它的资源。
Work = Work+ Allocationi
Finishi:= True go to 2
•如果所有进程的Finishi= True 则表示系统安全,否则为不安全。


一、系统安全性检查模块

方案一(不利用goto语句):

//判断系统的安全性
int judSystemSecurity()
{int i;//更新系统可利用资源量for (i = 0; i < resourseType; i++){work[i] = available[i];}int allFinish = 0;//把未完成进程置为0for (i = 0; i < customerNumber; i++){//判断当前进程是否已经完成并且可以回收资源//如果已经全部完成if (isFinish(i)){Finish[i] = 1;allFinish++;}else{Finish[i] = 0;}}int r = 0;//表示当前要判断是否要进行预分配的进程的下标int safeIndex = 0;//安全序列的下标int temp = 0;//临时变量int pNum = 0;//保存临时变量的个数//预分配开始,当进程没有全部完成时,一直执行循环while (allFinish != customerNumber){num = 0;//判断是否可以预分配for (i = 0; i < resourseType; i++){if (need[r][i] <= work[i] && Finish[r] == 0)//判断是否可以预分配{num++;}}//可以预分配if (num == resourseType){//输出进程Pr的各项信息SafeInfo(work, r);//回收资源for (i = 0; i < resourseType; i++){work[i] = work[i] + allocation[r][i];}//完成的进程数增加allFinish++;//保存安全序列safeSeries[safeIndex] = r;safeIndex++;//当前进程安全Finish[r] = 1;}r++;//该式必须在此处 if (r >= customerNumber){r = r % customerNumber;if (temp == allFinish)//temp记录的是上一次循环分配后所有的进程完成数,将上一次进程数跟这次预分配后的进程数{                    //进行对比,如果相等,则是不安全的情况,直接break;否则是安全的情况,继续执行break;}temp = allFinish;//更新完成的进程数}pNum = allFinish;//保存安全序列的个数}//判断系统是否安全for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){return 0;}}//打印安全序列printf("\n安全序列为:");for (i = 0; i < customerNumber; i++){if (isFinish(i)){pNum--;}}for (i = 0; i < pNum; i++){printf("%d ", safeSeries[i]);}return 1;
}

方案二(利用goto语句):

//方案二,利用goto语句
int judSystemSecurity_1()
{int i, j;for (i = 0; i < resourseType; i++){work[i] = available[i];}for (i = 0; i < customerNumber; i++){if (isFinish(i)){Finish[i] = 1;}else{Finish[i] = 0;}}int safeIndex = 0;NEXT:for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){for (j = 0; j < resourseType; j++){if (need[i][j] > work[j]){break;}}//已完全执行if (j == resourseType){Finish[i] = 1;SafeInfo(work, i);safeSeries[safeIndex++] = i;//回收资源for (j = 0; j < resourseType; j++){work[j] += allocation[i][j];}goto NEXT;}}}int pNum = 0;for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){return 0;}else{pNum++;}}//打印安全序列printf("\n安全序列为:");for (i = 0; i < customerNumber; i++){if (isFinish(i))//统计没完全执行的进程数{pNum--;}}for (i = 0; i < pNum; i++){printf("%d ", safeSeries[i]);}return 1;
}

二、资源申请模块:

//判断进程资源请求的安全性
void judRequestSecurity()
{//输入预分配的资源编号和各类资源量int curProcess;printf("请输入预分配资源的进程的编号:");scanf("%d", &curProcess);getchar();int i;for (i = 0; i < resourseType; i++){printf("请输入给 P%d 预分配的第 %d 类资源量:", curProcess, i + 1);scanf("%d", &request[i]);getchar();}//作为安全性的判断变量num = 0;//进行判断预分配是否合理for (i = 0; i < resourseType; i++){if (request[i] > need[curProcess][i]){printf("\n分配错误!请求分配资源量大于所需要的资源量!\n");printf("\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT OBTAIN RESOURCES IMMEDIATELY\n\n", curProcess);return;}else if (request[i] > available[i]){printf("\n分配错误!请求分配资源量大于可利用资源量!\n");printf("\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT OBTAIN RESOURCES IMMEDIATELY\n\n", curProcess);return;}else{num++;}}//分配合理,则试探性地分配if (num == resourseType){num = 0;for (i = 0; i < resourseType; i++){available[i] -= request[i];allocation[curProcess][i] += request[i];need[curProcess][i] -= request[i];if (need[curProcess][i] == 0){num++;}}//分配合理并且此次分配后该进程执行结束,回收资源if (num == resourseType){for (i = 0; i < resourseType; i++){available[i] += allocation[curProcess][i];}printf("\n进程 P%d 执行完毕,所占用资源全部释放!\n", curProcess);}else{printf("\n进程 P%d 未执行完毕,等待\n", curProcess);}}//检查分配后系统是否安全,如果不安全,则收回分配的资源printf("\n------------------------------------------------------------------------------------\n");printf("当前系统各类资源剩余量:");for (int i = 0; i < resourseType; i++){printf("%d ", available[i]);}printf("\n\n当前系统进程状况:\n");printf(" Name\t Work\t Need\tAllocation\tWork+Allocation\t Finish\n");if (!judSystemSecurity_1()){for (i = 0; i < resourseType; i++){available[i] += request[i];allocation[curProcess][i] -= request[i];need[curProcess][i] += request[i];}printf("\n\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT  OBTAIN RESOURCES IMMEDIATELY", curProcess);}else{printf("\n\nRESOURCE SECURITY!!!\n\nCUSTOMER P%d CAN OBTAIN RESOURCES IMMEDIATELY", curProcess);}printf("\n------------------------------------------------------------------------------------\n");return;
}

三、完整代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//系统中每种资源的可利用资源数
int available[100] = { 0 };
//进程的最大需求资源数
int max[100][100] = { 0 };
//系统刚开始每个进程已占用资源数
int allocation[100][100] = { 0 };
//每个进程还需要的资源数
int need[100][100] = { 0 };
//判断每个进程是否安全
int Finish[100] = { 0 };
//安全序列号
int safeSeries[100];
//进程请求资源量
int request[100];
//资源计数变量,便于判断安全性
int num;
//系统当前可分配资源量
int work[1000];
//资源种类数和进程数
int resourseType, customerNumber;
//作为是否输入数据的判断变量
int flag = 0;//函数声明
int isFinish(int row);
void SafeInfo(int* work, int index);
int judSystemSecurity();
int judSystemSecurity_1();
void judRequestSecurity();
void showMenu();
void keyDown();
void InitStastic();//函数定义
int isFinish(int row)
{int j;for (j = 0; j < resourseType; j++){if (need[row][j] != 0){return 0;}}return 1;
}//进程资源输出
void SafeInfo(int* work, int index)
{int j;printf(" P%d\t", index);for (j = 0; j < resourseType; j++){printf("%d ", work[j]);}printf("\t ");for (j = 0; j < resourseType; j++){printf("%d ", need[index][j]);}printf("\t  ");for (j = 0; j < resourseType; j++){printf("%d ", allocation[index][j]);}printf("\t  ");for (j = 0; j < resourseType; j++){printf("%d ", allocation[index][j] + work[j]);}printf("\t  T");printf("\n");return;
}//方案二,利用goto语句
int judSystemSecurity_1()
{int i, j;for (i = 0; i < resourseType; i++){work[i] = available[i];}for (i = 0; i < customerNumber; i++){if (isFinish(i)){Finish[i] = 1;}else{Finish[i] = 0;}}int safeIndex = 0;NEXT:for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){for (j = 0; j < resourseType; j++){if (need[i][j] > work[j]){break;}}//已完全执行if (j == resourseType){Finish[i] = 1;SafeInfo(work, i);safeSeries[safeIndex++] = i;//回收资源for (j = 0; j < resourseType; j++){work[j] += allocation[i][j];}goto NEXT;}}}int pNum = 0;for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){return 0;}else{pNum++;}}//打印安全序列printf("\n安全序列为:");for (i = 0; i < customerNumber; i++){if (isFinish(i))//统计没完全执行的进程数{pNum--;}}for (i = 0; i < pNum; i++){printf("%d ", safeSeries[i]);}return 1;
}//判断系统的安全性
int judSystemSecurity()
{int i;//更新系统可利用资源量for (i = 0; i < resourseType; i++){work[i] = available[i];}int allFinish = 0;//把未完成进程置为0for (i = 0; i < customerNumber; i++){//判断当前进程是否已经完成并且可以回收资源//如果已经全部完成if (isFinish(i)){Finish[i] = 1;allFinish++;}else{Finish[i] = 0;}}int r = 0;//表示当前要判断是否要进行预分配的进程的下标int safeIndex = 0;//安全序列的下标int temp = 0;//临时变量int pNum = 0;//保存临时变量的个数//预分配开始,当进程没有全部完成时,一直执行循环while (allFinish != customerNumber){num = 0;//判断是否可以预分配for (i = 0; i < resourseType; i++){if (need[r][i] <= work[i] && Finish[r] == 0)//判断是否可以预分配{num++;}}//可以预分配if (num == resourseType){//输出进程Pr的各项信息SafeInfo(work, r);//回收资源for (i = 0; i < resourseType; i++){work[i] = work[i] + allocation[r][i];}//完成的进程数增加allFinish++;//保存安全序列safeSeries[safeIndex] = r;safeIndex++;//当前进程安全Finish[r] = 1;}r++;//该式必须在此处 if (r >= customerNumber){r = r % customerNumber;if (temp == allFinish)//temp记录的是上一次循环分配后所有的进程完成数,将上一次进程数跟这次预分配后的进程数{                    //进行对比,如果相等,则是不安全的情况,直接break;否则是安全的情况,继续执行break;}temp = allFinish;//更新完成的进程数}pNum = allFinish;//保存安全序列的个数}//判断系统是否安全for (i = 0; i < customerNumber; i++){if (Finish[i] == 0){return 0;}}//打印安全序列printf("\n安全序列为:");for (i = 0; i < customerNumber; i++){if (isFinish(i)){pNum--;}}for (i = 0; i < pNum; i++){printf("%d ", safeSeries[i]);}return 1;
}//判断进程资源请求的安全性
void judRequestSecurity()
{//输入预分配的资源编号和各类资源量int curProcess;printf("请输入预分配资源的进程的编号:");scanf("%d", &curProcess);getchar();int i;for (i = 0; i < resourseType; i++){printf("请输入给 P%d 预分配的第 %d 类资源量:", curProcess, i + 1);scanf("%d", &request[i]);getchar();}//作为安全性的判断变量num = 0;//进行判断预分配是否合理for (i = 0; i < resourseType; i++){if (request[i] > need[curProcess][i]){printf("\n分配错误!请求分配资源量大于所需要的资源量!\n");printf("\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT OBTAIN RESOURCES IMMEDIATELY\n\n", curProcess);return;}else if (request[i] > available[i]){printf("\n分配错误!请求分配资源量大于可利用资源量!\n");printf("\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT OBTAIN RESOURCES IMMEDIATELY\n\n", curProcess);return;}else{num++;}}//分配合理,则试探性地分配if (num == resourseType){num = 0;for (i = 0; i < resourseType; i++){available[i] -= request[i];allocation[curProcess][i] += request[i];need[curProcess][i] -= request[i];if (need[curProcess][i] == 0){num++;}}//分配合理并且此次分配后该进程执行结束,回收资源if (num == resourseType){for (i = 0; i < resourseType; i++){available[i] += allocation[curProcess][i];}printf("\n进程 P%d 执行完毕,所占用资源全部释放!\n", curProcess);}else{printf("\n进程 P%d 未执行完毕,等待\n", curProcess);}}//检查分配后系统是否安全,如果不安全,则收回分配的资源printf("\n------------------------------------------------------------------------------------\n");printf("当前系统各类资源剩余量:");for (int i = 0; i < resourseType; i++){printf("%d ", available[i]);}printf("\n\n当前系统进程状况:\n");printf(" Name\t Work\t Need\tAllocation\tWork+Allocation\t Finish\n");if (!judSystemSecurity_1()){for (i = 0; i < resourseType; i++){available[i] += request[i];allocation[curProcess][i] -= request[i];need[curProcess][i] += request[i];}printf("\n\nRESOURCE INSECURITY!!!\n\nCUSTOMER P%d CAN NOT  OBTAIN RESOURCES IMMEDIATELY", curProcess);}else{printf("\n\nRESOURCE SECURITY!!!\n\nCUSTOMER P%d CAN OBTAIN RESOURCES IMMEDIATELY", curProcess);}printf("\n------------------------------------------------------------------------------------\n");return;
}//菜单
void showMenu()
{printf("  ====================菜单栏=====================\n");printf("\n\t       0、input datas\n");printf("\n\t       1、judge the system security\n");printf("\n\t       2、judge the request security\n");printf("\n\t       3、quit\n");printf("\n  ===============================================\n");return;
}//检测用户按键输入
void keyDown()
{NEXT:;int hit;printf("请输入你的选择:");scanf("%d", &hit);switch (hit){case 0:NEXT_1:flag = 1;InitStastic();break;case 1://判断系统安全性if (flag){printf("\n------------------------------------------------------------------------------------\n");printf("当前系统各类资源剩余量:");for (int i = 0; i < resourseType; i++){printf("%d ", available[i]);}printf("\n\n当前系统进程状况:\n");printf(" Name\t Work\t Need\tAllocation\tWork+Allocation\t Finish\n");if (judSystemSecurity_1()){printf("\n\nSYSTEM SECURITY!!!");}else{printf("\n\nSYSTEM  INSUFFICIENT!!!");}printf("\n------------------------------------------------------------------------------------\n");}else{printf("还未输入数据!请先输入相关数据\n");goto NEXT_1;}break;case 2://判断进程请求的安全性if (flag){judRequestSecurity();}else{printf("还未输入数据!请先输入相关数据\n");goto NEXT_1;}break;case 3://退出printf("\n正常退出!\n");exit(-1);default:printf("\n输入错误,请重新输入指令!\n");system("pause");system("cls");showMenu();goto NEXT;break;}
}void InitStastic()
{printf("Input the type of resource and number of customer:\n");scanf("%d%d", &resourseType, &customerNumber);getchar();printf("\nInput the amount of resource (maximum , allocated) of each customer:\n");int i, j;for (i = 0; i < customerNumber; i++){for (j = 0; j < resourseType; j++){printf("请输入进程 P%d 的第 %d 类资源的最大需求量:", i, j + 1);scanf("%d", &max[i][j]);getchar();}printf("\n\n");for (j = 0; j < resourseType; j++){printf("请输入进程 P%d 的第 %d 类资源的已占用资源量:", i, j + 1);scanf("%d", &allocation[i][j]);getchar();}printf("\n\n");for (j = 0; j < resourseType; j++){need[i][j] = max[i][j] - allocation[i][j];}}printf("\nInput  the amout of  resources(available):\n");for (i = 0; i < resourseType; i++){printf("请输入第%d类资源的可利用量:", i + 1);scanf("%d", &available[i]);getchar();}printf("\n数据录入成功!\n");return;
}int main(int argc, char* argv[])
{while (1){showMenu();keyDown();system("pause");system("cls");}return 0;
}

菜单栏:

输入示例:



输出示例:



有任何问题可以留言交流,我一定及时回复

操作系统-资源分配银行家算法相关推荐

  1. 操作系统之银行家算法—详解流程及案例数据

    操作系统之进程调度--优先权法和轮转法(附上样例讲解) 操作系统之银行家算法-详解流程及案例数据 操作系统之多线程编程-读者优先/写者优先详解 操作系统之存储管理--FIFO算法和LRU算法 操作系统 ...

  2. 操作系统之银行家算法解析

    操作系统之银行家算法解析(带例题) 利用银行家算法避免死锁,首先我们先来明晰一下银行家算法的数据结构,其中必须设置四个数据结构,Available,Max,Allocation,Need. Avail ...

  3. 操作系统 进程调度-银行家算法实验报告

    实验要求 一. 实验目的 死锁会引起计算机工作僵死,因此操作系统中必须防止.本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家 ...

  4. 计算机操作系统实验银行家算法,实验六 银行家算法(下)

    实验六 银行家算法(下) 一.实验说明 实验说明:本次实验主要是对银行家算法进行进一步的实践学习,掌握银行家算法的整体流程,理解程序测试时每一步的当前状态,能对当前的资源分配进行预判断. 二.实验要求 ...

  5. 【计算机操作系统】银行家算法的模拟实现

    文章目录 前言 1 实验相关知识理论 1.1 死锁的概念 1.2 产生死锁的原因 1.3 避免死锁的方法 1.4 解除死锁的方法 2 实验设计思路 3 实验设计涉及到的数据结构 4 程序算法设计 4. ...

  6. 操作系统知识——银行家算法

    用自己理解的语言描述,如有错误,请疯狂打脸没关系,希望能够指出来. 0. 主要思想 分配资源之前,判断系统是否安全. 银行家算法是一种资源分配和避免死锁的算法,它通过模拟所有资源的分配方式来测试安全性 ...

  7. 计算机操作系统_银行家算法

    银行家算法 什么是银行家算法? 银行家算法(Banker's Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生 ...

  8. 【操作系统】-- 银行家算法

    银行家算法是Dijkstra为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况,后来被用于操作系统中,用于避免死锁. 核心思想:在进程提出资源申请时,先预判此次分配是否会 ...

  9. 【操作系统】银行家算法:算法分析 + 运行结果 + 完整代码

    学习网站推荐:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到网站 一.银行家算法 可利用银行家算法避免死锁,请设计银行家算法,参考教材依据教材<计算 ...

最新文章

  1. [原创]微软网络协议数据分析工具 Microsoft Network Monitor 介绍
  2. SAP软件项目实施要点
  3. Html、Css-----当有文字和图片的时候,需要文字和图片居中,怎么实现?不想文字换行怎么设置...
  4. SpringMVC日期类型转换问题处理方法归纳
  5. 阿里云实时数仓Hologres年度发布,解读数仓新趋势
  6. 运维linux脚本实例,Shell脚本使用示例
  7. c/c++教程 - 2.4.4 友元friend用法
  8. 传统JDBC的弊病和mybatis的解决方案
  9. too many files open
  10. 用Javascript读取CheckBox数组的值
  11. 挑战程序设计竞赛题解目录
  12. unity 关于Particles shader的alpha通道存储(用于bloom效果)
  13. [笔记]_ELVE_正则表达式
  14. word在试图打开文件时遇到错误,解决办法
  15. 数据管理平台(DMP)简介
  16. log4j连接ekl
  17. Xshell和Xftp使用(非商业用途可以免费使用啦)
  18. Android 高德地图so包太大,高德地图sdk配置心得(jar文件与so文件导入)
  19. IGES格式文件分析 / IGES File Format
  20. 京东案例开发之居家优品

热门文章

  1. Sniffer的讨论
  2. 使用html+css+js实现一个静态页面(含源码)
  3. 比较好看的背景html,一个超炫的Canvas背景,做网页背景挺好看
  4. 30岁的我们,没车没房没存款。
  5. 吕鑫:VC++6.0就业培训宝典之MFC视频教程
  6. 记录——红外成像光学系统进展与展望
  7. php调度服务,cron自动调度服务配置详解
  8. python查看网速,python如何查看系统网络流量的信息
  9. 现代农业|AIRIOT智慧农业管理解决方案
  10. 国内访问mega网盘 的方法