OS 之 避免死锁(银行家算法)

来源:互联网 发布:完美国际js是什么意思 编辑:程序博客网 时间:2024/05/17 06:36

这是我们操作系统的一个上机实习的课题。


虽然代码看起来有点长,实际上都是输入输出,核心代码就是银行家算法(bankerAlgorithm()),以及安全性算法(SecurityAlgorithm())

懂得人都明白原理不难,只是按照我们老师要求的界面输入输出排版难受。


首先我们来了解一下银行家算法

银行家算法(Banker's Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行

1)可利用资源向量Available

是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。

2)最大需求矩阵Max

这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵Allocation

这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。

4)需求矩阵Need。

这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。

Need[i,j]=Max[i,j]-Allocation[i,j]


详情请参考百度百科:点击打开链接


然后我们来了解一下银行家算法的流程图:

下面是代码实现

(1)银行家算法类:

import java.util.Scanner;public class BankerClass {int available[];int availableContinue[];int max[][];int allocation[][];int allocationContinue[][];int need[][];int needContinue[][];int request[][];int work[];int a;//进程数int b;//资源种类int num=0;//进程编号 Scanner sc=new Scanner(System.in);public BankerClass(int a,int b) {super();this.a=a;this.b=b;this.available=new int[b];this.availableContinue=new int[b];this.max=new int[a][b];this.allocation=new int[a][b];this.allocationContinue=new int[a][b];this.need=new int[a][b];this.needContinue=new int[a][b];this.request=new int[a][b];this.work=new int[b];}public void setSystemVariable(){//设置各初始系统变量,并判断是否安全setMax();setAllocation();setAvailable();printSystemVariable();SecurityAlgorithm();}private void setMax() {//设置Max最大需求矩阵System.out.println("请输入Max矩阵:");for(int i=0;i<a;i++){for(int j=0;j<b;j++){max[i][j]=sc.nextInt();}}}private void setAllocation() {//设置以分配矩阵AllocationSystem.out.println("请输入Allocation矩阵:");for(int i=0;i<a;i++){for(int j=0;j<b;j++){allocation[i][j]=sc.nextInt();}}//计算需求矩阵for(int i=0;i<a;i++){for(int j=0;j<b;j++){need[i][j]=max[i][j]-allocation[i][j];//available[j]-=allocation[i][j];}}}private void setAvailable() {System.out.println("请输入Available矩阵");for(int i=0;i<b;i++){available[i]=sc.nextInt();}}private void printSystemVariable() {//打印资源分配表System.out.println("**********************此时资源分配情况******************");System.out.println("    进程名/号     "+"    max    "+"  allocation "+"     need   ");for(int i=0;i<a;i++){System.out.print("  P"+i+"/"+i+"  ");for(int j=0;j<b;j++){System.out.print("  "+max[i][j]);}System.out.print("  "+"|");for(int j=0;j<b;j++){System.out.print("  "+allocation[i][j]);}System.out.print("  "+"|");for(int j=0;j<b;j++){System.out.print("  "+need[i][j]);}System.out.print("  "+"|");System.out.println();}System.out.print("各类资源可利用资源数为:");for(int j=0;j<b;j++){System.out.print("  "+available[j]);if(j==b-1){System.out.println();}}System.out.println();}private void SecurityAlgorithm() {//安全算法//(1):设置2个向量work=availableboolean finish[]=new boolean[a];for(int i=0;i<a;i++){finish[i]=false;}int count=0;//满足安全性算法的进程个数int circle=0;int security[]=new int[a];//满足安全性算法的进程号for(int i=0;i<b;i++){work[i]=available[i];}while(count<a){for(int i=0;i<a;i++){//(2):从进程集合中找到一个能满足//(1)finish[i]=false;//(2)need[i][j]<=work[j];boolean t=true;for(int j=0;j<b;j++){if(need[i][j]>work[j]){t=false;}}if(!finish[i]&&t){//若找到,执行步骤(3):释放出分配给它的资源//(1):work[j]=work[j]+allocation[i][j];//(2):finish[i]=true;//(3):go to step 2;for(int j=0;j<b;j++){work[j]+=allocation[i][j];}finish[i]=true;security[count]=i;count++;}circle++;if(count==a){//若没找到则执行步骤4://(4):如果所有进程的finish[i]=true;都满足,则表示系统处于安全状态;否则系统处于不安全状态System.out.print("系统当前为安全状态,");System.out.println("安全序列为:");for(int j=0;j<a;j++){System.out.print("P"+security[j]);if(j!=a-1){System.out.print("  ");}else{System.out.println();}}break;}if(circle>=a*a){count=a;//执行步骤4后就跳出循环System.out.println("当前系统处于不安全状态,返回分配前资源数");for(int i1=0;i1<a;i1++){for(int j=0;j<b;j++){available[j]=availableContinue[j];allocation[i1][j]=allocationContinue[i1][j];need[i1][j]=needContinue[i1][j];}}printSystemVariable();break;}}}}public void setRequest(){System.out.println("请输入请求资源的进程号:0~"+(a-1));num=sc.nextInt();//进程编号(在这里为全局变量)System.out.println("请输入该进程所请求的资源数request[j]:");for(int i=0;i<3;i++){request[num][i]=sc.nextInt();}bankerAlgorithm();//设置完请求资源矩阵后,进行银行家算法}private void bankerAlgorithm() {//银行家算法boolean t=true;//(1):如果request[num][j]<=need[num][j]==>num表示请求分配资源的进程boolean t1=true;for(int i=0;i<b;i++){if(request[num][i]>need[num][i]){t1=false;}}if(t1){//(2):如果满足步骤1:转向步骤2:request[num][j]<=available[j]boolean t2=true;for(int i=0;i<b;i++){if(request[num][i]>available[i]){t2=false;}}if(t2){//(3):系统试探着把资源分配给进程P(num),并修改数据//1:available[i]=available[i]-request[num][i];//2:allocation[num][i]+=request[num][i];//3:need[num][i]=need[num][i]-request[num][i];//availableContinue=available;//allocationContinue=allocation;//needContinue=need;for(int i=0;i<a;i++){for(int j=0;j<b;j++){allocationContinue[i][j]=allocation[i][j];needContinue[i][j]=need[i][j];availableContinue[j]=available[j];}}for(int i=0;i<b;i++){available[i]=available[i]-request[num][i];allocation[num][i]+=request[num][i];need[num][i]=need[num][i]-request[num][i];}}else{System.out.println("当前没有足够资源可供分配,请求失败");t=false;}}else{System.out.println("进程P"+num+"请求资源已经超过最大需求量need");t=false;}if(t){//打印printSystemVariable();//进入安全性算法SecurityAlgorithm();}}}
(2)测试类:package girls2017;import java.util.Scanner;public class TestBankerClass {public static void main(String[] args) {Scanner in=new Scanner(System.in);boolean isContinue=true;System.out.println("*****************************************************");System.out.println("*                  银行家算法的设计与实现                                    *");System.out.println("*****************************************************");System.out.println("请输入进程总数:");int a=in.nextInt();System.out.println("请输入资源类数:");int b=in.nextInt();BankerClass banker=new BankerClass(a,b);banker.setSystemVariable();while(isContinue){banker.setRequest();System.out.println("你还要继续分配吗?Y or N");String s=in.next();if(s.equals("n")||s.equals("N")){isContinue=false;}}}}

测试数据如下:
1:初始化测试数据



2:检查请求分配资源的进程是否仍然存在安全序列






原创粉丝点击