完成与:2013.12.11左右

1. 算法思想

银行家算法是为了避免死锁的算法,是Dijkstra的银行家算法。由于该算法用于实现银行系统现金贷款的发放而得名的。为实现银行家算法,系统中必须设置若干数据结构。

1) 银行家算法的数据结构

a) 可利用资源向量available

b) 最大需求矩阵

c) 分配矩阵

d) 需求矩阵

2) 银行家算法

设Requesti 是进程Pi的请求量,如果Requesti[j]=k,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查。

a) 如果Requesti[j] <=Need[I,j],便转向步骤(b);否则认为出错,因为他所需要的资源数已经超过它所宣布的最大值。

b) 如果Requesi[j] <=Available[j],便转向步骤(c);否则,表示尚无足够的资源,Pi须等待。

c) 系统试探着把资源分配给进程Pi,并修改下面的数据结构中的数值:

Available[j] := Available[j] – Request i[j];

Allocation[i, j] :=Allocation[i, j] + Request i[j];

Need[i, j] := Need[i, j] – Request i[j];

d) 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,已完成本次资源的分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

3) 安全算法

系统所执行的安全算法可描述如下:

(1) 设置两个向量:

① 工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work :=Available。

② Finish,他表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish := false;当有足够资源分配给进程时,再令Finish[i] :=true。

(2) 从进程集合中找到一个满足下述条件的进程:

① Finish[i] := false;

② Need[i, j] <= Work[j]; 若找到,执行步骤(3),否则,执行步骤(4)。

(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给他的资源,故应执行:

Work[j] :=Work[j] + Allocation[i, j];

Finish[i] :=true;

Go to step2;

(4) 如果所有进程的Finish[i] = true 都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

2. 程序代码

#include <stdio.h>
#include <stdlib.h>
#include "head.h"
#include <string.h>
#include <windows.h>#define PRONUM 80 //进程的最大数目
#define RESNUM 80   //资源的最大数目
#define RESLEN 80   //资源名的最大数目
typedef struct Max_Allocation//进程已分配资源量
{char           proName[PRONUM];//进程名int                iMax[RESNUM];//最大需求量int             iAllocation[RESNUM];//进程已分配资源量int               need[RESNUM];//需求量
}Max_Allocation;
struct course
{Max_Allocation res;//资源需求与分配信息int              finish;//是否访问的标志。(0未访问,1已经访问)
};
char         resName[RESNUM][RESLEN];//资源名
int      work[RESNUM];//可用资源数
int      request[RESNUM]={0};//请求资源
char         safe_Array[RESNUM][RESLEN];//资源名
int      available[RESNUM];//可用资源
struct course progress[80];
void health_Examination(int proNum, int resNum)
{return; }///
//此处仅供调试方便
//
void test(){
progress[0].res.iMax[0]=7;progress[0].res.iMax[1]=5;progress[0].res.iMax[2]=3;progress[0].res.iAllocation[0]=0;progress[0].res.iAllocation[1]=1;progress[0].res.iAllocation[2]=0;progress[1].res.iMax[0]=3;progress[1].res.iMax[1]=2;progress[1].res.iMax[2]=2;progress[1].res.iAllocation[0]=2;progress[1].res.iAllocation[1]=0;progress[1].res.iAllocation[2]=0;progress[2].res.iMax[0]=9;progress[2].res.iMax[1]=0;progress[2].res.iMax[2]=2;progress[2].res.iAllocation[0]=3;progress[2].res.iAllocation[1]=0;progress[2].res.iAllocation[2]=2;progress[3].res.iMax[0]=2;progress[3].res.iMax[1]=2;progress[3].res.iMax[2]=2;progress[3].res.iAllocation[0]=2;progress[3].res.iAllocation[1]=1;progress[3].res.iAllocation[2]=1;progress[4].res.iMax[0]=4;progress[4].res.iMax[1]=3;progress[4].res.iMax[2]=3;progress[4].res.iAllocation[0]=0;progress[4].res.iAllocation[1]=0;progress[4].res.iAllocation[2]=2;strcpy(progress[0].res.proName, "P0");strcpy(progress[1].res.proName, "P1");strcpy(progress[2].res.proName, "P2");strcpy(progress[3].res.proName, "P3");strcpy(progress[4].res.proName, "P4");strcpy(resName[0], "A");strcpy(resName[1], "B");strcpy(resName[2], "C");
}void init_Flag(int proNum, int resNum) {int i=0;for(i=0; i<proNum; i++){progress[i].finish=0;//访问标志初始化}return;
}
void init_Resource(int proNum, int resNum)//初始化资源
{int i=0, j=0;for(i=0; i<proNum; i++){for(j=0; j<resNum; j++){progress[i].res.iMax[j]=0;//最大需求量,初始化为0progress[i].res.iAllocation[j]=0;//进程已分配资源量,初始化为0}}return;
}
//初始化需求量
void init_Need(int proNum, int resNum)
{int i=0, j=0;for(i=0 ; i<proNum; i++){for(j=0 ; j<resNum; j++){progress[i].res.need[j]=0;}}return;
}
//初始化可用资源
void init_Available(int resNum) {
int i=0;for(i=0; i<resNum; i++){available[i]=0;}return;
}//输入进程名,资源名,以及进程信息等
void input_info(int proNum, int resNum) {int i=0, j=0;for(i=0; i<proNum; i++){printf("请输入第%d个进程名<共%d>: ", i+1, proNum);scanf("%s", progress[i].res.proName);for(j=0; j<resNum; j++){if(i==0) {printf("    请输入第%d个资源类型名<共%d>: ", j+1, resNum);scanf("%s", resName[j]);}printf("        请输入%s类资源的最大需求量: ", resName[j]);scanf("%d", &progress[i].res.iMax[j]);printf("        请输入%s类资源的当前已分配量: ", resName[j]);scanf("%d", &progress[i].res.iAllocation[j]);printf(" \n");}printf(" \n");}return;
}//给need赋值
void voluation_Need(int proNum, int resNum) {int i=0,j=0;for(i=0; i<proNum; i++){for(j=0; j<resNum; j++){progress[i].res.need[j]=progress[i].res.iMax[j] - progress[i].res.iAllocation[j];}}return;
}
//对可用资源的输入
void input_Available( int resNum) {int i=0;for(i=0; i<resNum; i++){printf("请输入%s类资源的可用数(按回车结束一类资源的输入): ", resName[i]);scanf("%d", &available[i]);/*if( available[i] == 'q' || available[i] == 'Q')//退出检测{printf("\n\n程序结束。\n");exit(0);}*/}return;
}
//初始化work
void init_Work( int resNum) {int i=0;for(i=0; i<resNum; i++){work[i]=*(available+i);}return;
}
//
//
//以下为整个程序的核心代码
//
///
//此处完成合法性的检查,判断系统是否安全
bool check_safety(int proNum, int resNum) {int i=0, j=0, Need=0, countPro=0, countFor=0, countLastPro=0, countFinish=0;//countFor统计循环的次数,countFinish统计已访问的次数int num=0;while(countPro < proNum ) {for(i=0; i<proNum; i++){if ( progress[i].finish != 1)//判断该进程是否已经被访问{for(j=0; j<resNum; j++){Need=progress[i].res.iMax[j] - progress[i].res.iAllocation[j]; if( Need <= work[j] ) {continue; }else{break; }}if(j == resNum) {for(j=0; j<resNum; j++){work[j]=work[j] + progress[i].res.iAllocation[j];//资源拥有量}strcpy(safe_Array[num++], progress[i].res.proName);progress[i].finish=1;//把已访问的进程置1countPro++;//统计访问进程的个数}}}//以下两个判断都能够满足安全性的检查//判断1,效率高if(countLastPro == countPro){//判断上一次循环统计的进程个数是否等于本次循环的进程个数,//若相等则说明可用资源不能满足当前进程的运行return false;}else{//若相等把这次的进程个数赋给上一次统计的个数countLastPro = countPro; }//判断2,效率低countFor++;//统计循环的次数,若循环次数大于当前进程的个数,则说明可用资源不能满足当前进程的运行if(countFor > proNum)//此处proNum加1,是为了防止与countPro相悖{return false; }}return true;
}
//输入请求进程请求名
int input_Request_Name(int proNum) {int position=0;char reqProName[PRONUM];bool flag=true;int i=0;printf("\n***********************************\n");while(flag) {printf("按“q”、“Q”结束程序。\n");printf("请输入资源请求的进程名:");scanf("%s", reqProName);if( strcmp(reqProName, "q") ==0 || strcmp(reqProName, "Q") ==0)//退出检测{printf("\n\n程序结束。\n");exit(0);}for(i=0; i<proNum; i++){if( strcmp(progress[i].res.proName, reqProName)==0 ) {position=i;flag=false;break;}}if( proNum == i){printf("\n您输入的进程不存在。\n");}}return position;
}
//输入各类资源请求数
bool input_Res_Num(int proNum, int resNum, int *available, int position) {bool flag=false;int need=0;int i=0, iflag=-1;//char over; printf("\n*************************************\n");printf("请输入资源请求量共%d种。\n", resNum);for(i=0; i<resNum; i++){printf("请输入第%s类资源请求: ", resName[i]);scanf("%d", &request[i]);/*if( request[i] == 89)//退出检测{printf("\n\n程序结束。\n");exit(0);break;}*/}//此处判断request<=Need 并且 request<=Availablefor(i=0; i<resNum; i++){need=progress[position].res.iMax[i] - progress[position].res.iAllocation[i];if (request[i] > need  ) {printf("资源请求量大于需求资源量,资源不分配\n");print_Info(proNum, resNum);//输出信息return false;}if ( request[i] > available[i] ) {printf("资源请求量大于可用资源量,资源不分配\n");print_Info(proNum, resNum);//输出信息return false;}}print_Info(proNum, resNum);//输出信息return true;
}
//请求资源
void request_Resource(int proNum, int resNum, int *available) {bool flag=false, allFlag=true;int position=0, need=0;int i=0; while(!flag) {position = input_Request_Name(proNum);//输入资源请求名flag = input_Res_Num(proNum, resNum, available, position);}init_Flag(proNum, resNum);init_Work(resNum);//初始化可用资源for(i=0; i<resNum; i++){progress[position].res.iAllocation[i] += request[i];work[i] -= request[i];}if( check_safety(proNum, resNum) ) {for(i=0; i<resNum; i++)//need值改变{progress[position].res.need[i] -= request[i]; }for(i=0; i<resNum; i++)//available值改变{available[i] -= request[i]; }printf("安全序列是:\n");printf("%s", safe_Array[0]);for(i=1; i<proNum; i++){printf("->%s", safe_Array[i]); }putchar('\n'); printf("\n此状态安全。\n");}else{printf("\n此状态不安全,资源不分配。\n");for(i=0; i<resNum; i++){progress[position].res.iAllocation[i] -= request[i]; }}return;
}
//格式输出
void print_Info(int proNum, int resNum) {int i=0, j=0;printf("\n**************************************************************************************************\n");printf("********************                操作系统之银行家算法              ****************************\n");printf("**************************************************************************************************\n");printf("资源情况       Max\t     \t    Allocation\t      \t      Need\t      \t    Available\n");printf("进程");for(i=0; i<resNum; i++){printf("\t%s", resName[i]); }for(i=0; i<resNum; i++){printf("\t%s", resName[i]); }for(i=0; i<resNum; i++){printf("\t%s", resName[i]); }for(i=0; i<resNum; i++){printf("\t%s", resName[i]); }printf("\n\n");for(i=0; i<proNum; i++){printf("%s", progress[i].res.proName); for(j=0; j<resNum; j++){printf("\t%d", progress[i].res.iMax[j]); }for(j=0; j<resNum; j++){printf("\t%d", progress[i].res.iAllocation[j]); }for(j=0; j<resNum; j++){printf("\t%d", progress[i].res.need[j]); }for(j=0; j<resNum && i==0; j++){printf("\t%d", available[j]); }printf(" \n");}printf(" \n**************************************************************************************************\n");return;
}
//初始化所有需初始化
void init_All(int proNum, int resNum)init_Flag(proNum, resNum);//初始化相应的信息init_Resource(proNum, resNum);//初始化资源init_Need(proNum, resNum);//need初始化init_Available(resNum);//初始化可用资源test();//input_info(proNum, resNum);//输入相应信息voluation_Need(proNum, resNum);//给need赋值print_Info(proNum, resNum);//输出相应信息input_Available(resNum);//可用资源init_Work(resNum);//初始化可用资源
}
int main(int argc,char* argv[])
{int proNum=5, resNum=3;char ch=' ';bool is_safe=false;int i=0;system("title 操作系统之银行家算法  作者:宋腾飞");system("mode con cols=100 lines=30 ");//while(!is_safe) {//printf("请输入进程数及资源数:");//scanf("%d%c%d", &proNum, &ch, &resNum); //health_Examination(proNum); init_All(proNum, resNum); if( check_safety(proNum, resNum) ){printf("\n此状态安全。\n");printf("安全序列是:\n");printf("%s", safe_Array[0]);for(i=1; i<proNum; i++){printf("->%s", safe_Array[i]); }putchar('\n'); is_safe=true; print_Info(proNum, resNum);}else{printf("\n此状态不安全。等待5秒钟后请重新输......\n");is_safe=false;Sleep(5000);//system("cls");}}printf("请等待5秒......\n");Sleep(5000); do{//system("cls");request_Resource(proNum, resNum, available); }while(1); //print_Info(proNum, resNum);//输出相应信息return 0;
}

3. 运行结果

操作系统之银行家算法实现代码相关推荐

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

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

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

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

  3. 操作系统 | 银行家算法及代码实现

    参考博客 [操作系统]死锁避免之银行家算法_少侠露飞的学习笔记-CSDN博客 [操作系统]避免死锁--银行家算法_明昕ztoy的博客-CSDN博客_银行家算法避免死锁 实现思路 当一个进程申请使用资源 ...

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

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

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

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

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

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

  7. 操作系统-资源分配银行家算法

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

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

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

  9. 操作系统实验——银行家算法

    文章目录 一.实验目的 二.实验内容和要求 三.实验原理 算法实现 四.实验程序 代码如下: 五.验证数据和运行结果 运行结果截图 六.思考与分析 附 一.实验目的 掌握银行家算法思想,并能编程实现. ...

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

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

最新文章

  1. Reallusion Character Creator 3中文版
  2. Matlab画图,去掉周围白边
  3. Java实现把一个对象复制给另一个有相同字段属性的对象
  4. java convexhull_图像上划凸多边形(convexHull()函数)
  5. aspnetboilerplate .net core 使用原生sql
  6. Git push 时每次都需要密码的疑惑
  7. Machine Learning - III. Linear Algebra Review线性代数 (Week 1, Optional)
  8. 微信实现双向跨境支付,将向香港用户开放内地支付服务
  9. 灰鸽子***猛增五百多变种 网民生活受***监控
  10. css电子表数字,使用css实现电子数字效果
  11. Lvgl(V8.2)自定义字体实现多国语言切换功能
  12. 多媒体计算机辅助英语教学,多媒体计算机辅助英语教学
  13. 【敏捷开发模式的介绍】
  14. 路由器实验要求之配置实验、直连路由验证、静态路由
  15. 单体架构常用注解合集
  16. 深度linux软件中心 qq,ubuntu上安装QQ(包括多个软件安装方法)
  17. ChatGPT搞砸了~,如何使用VBA导出Word文档中的图片
  18. 判决文书网爬虫获取vjkl5失败原因
  19. 数据分析与挖掘(一)误差与精度
  20. 【VMware Fusion】如何配置VMware Fusion中的Vmnet网卡

热门文章

  1. 一键式文件共享软件Jirafeau
  2. 为什么要进行TracePro模拟?
  3. 魅族16Xs评测:集“够用”与性价比于一身
  4. 微信小程序豆瓣电影实例源码下载
  5. 人工智能深度学习数据集
  6. Apple Pay接入详细教程
  7. 上古计算机语言,微软开源其上古编程语言GW-BASIC
  8. php在线拍照代码,PHP+Javascript实现在线拍照功能实例
  9. Adobe FLASH CS6 安装错误解决方法
  10. C#: PDF转图片(ghostscript)