一、实验内容
银行家算法的实现。
二、实验目的
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。通过编写一个模拟动态资源分配的银行家算法程序,帮助学生进一步深入理解死锁、产生死锁的必要条件、安全状态等重要概念,并掌握避免死锁的具体实施方法。
三、实验原理
3.1、银行家算法中的数据结构
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]
3.2、银行家算法
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
- (1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。
- (2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
- (3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
1 2 3 4 5
| Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];
|
系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
3.3、安全性算法
1)设置两个向量:
工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available;
工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。
2)从进程集合中找到一个能满足下述条件的进程:
1 2
| Finish[i]=false; Need[i,j]≤Work[j];
|
若找到,执行 (3),否则,执行 (4)
3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
1 2 3
| Work[j]= Work[i]+Allocation[i,j]; Finish[i]= true; go to step 2;
|
4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态
四、代码实现
1、创建进程类(多个进程)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import java.util.Scanner;
public class Processes { private String[] resourceName; //系统资源名称 private Integer[][] maxNum; //Pi的需求资源数量(最大需求资源数量) private Integer[][] allocation; //已分配给该进程的资源 private Integer[][] needNum; //还需要的资源数量 private Integer AVAILABLE_COUNT_Y;//资源的种类数量 private Integer PROCESSES_COUNT; //进程的个数 public Processes() { Init(); }
public Integer getAVAILABLE_COUNT_Y() { return AVAILABLE_COUNT_Y; }
public void setAVAILABLE_COUNT_Y(Integer AVAILABLE_COUNT_Y) { this.AVAILABLE_COUNT_Y = AVAILABLE_COUNT_Y; }
public Integer getPROCESSES_COUNT() { return PROCESSES_COUNT; }
public void setPROCESSES_COUNT(Integer PROCESSES_COUNT) { this.PROCESSES_COUNT = PROCESSES_COUNT; }
public String getResourceName(int j) { return resourceName[j]; }
public void setResourceName(String[] resourceName) { this.resourceName = resourceName; }
public Integer[][] getMaxNum() { return maxNum; }
public void setMaxNum(Integer[][] maxNum) { this.maxNum = maxNum; }
public Integer getAllocation(int i,int j) { return allocation[i][j]; }
public void setAllocation(int i,int j,Integer allo) { allocation[i][j] = allo; }
public Integer getNeedNum(int i,int j) { return needNum[i][j]; }
public void setNeedNum(int i,int j,Integer need) { needNum[i][j] = need; }
/** * 初始化 */ public void Init() { System.out.print("请输入资源的种类数量:"); Scanner input = new Scanner(System.in); AVAILABLE_COUNT_Y = input.nextInt(); resourceName = new String[AVAILABLE_COUNT_Y]; System.out.println("请输入各类资源的名称:"); for (int i = 0; i < AVAILABLE_COUNT_Y; i++) { System.out.print("资源" + (i+1) + "的名称:"); resourceName[i] = input.next(); }
System.out.println("请输入进程的个数:"); PROCESSES_COUNT = input.nextInt(); maxNum = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y]; allocation = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y]; needNum = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y]; for (int i = 0; i < PROCESSES_COUNT; i++) { System.out.println("请输入进程" + (i+1) + "对" + AVAILABLE_COUNT_Y + "类资源的最大需求:"); for (int j = 0; j < AVAILABLE_COUNT_Y; j++) { System.out.print(resourceName[j] + ":"); maxNum[i][j] = input.nextInt(); }
System.out.println("请输入进程" + (i+1) + "已申请到的各类资源数:"); for (int j = 0; j < AVAILABLE_COUNT_Y; j++) { System.out.print(resourceName[j] + ":"); allocation[i][j] = input.nextInt(); }
for (int j = 0; j < AVAILABLE_COUNT_Y; j++) { needNum[i][j] = maxNum[i][j] - allocation[i][j]; }
} } }
|
2、创建银行家类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| import java.util.Scanner;
public class Banker { private Integer[][] request; //进程的请求向量 private Integer[] available; //可利用资源向量 /** * 银行家算法 */ public void Bank(){ Processes processes = new Processes(); Scanner input = new Scanner(System.in); request = new Integer[processes.getPROCESSES_COUNT()][processes.getAVAILABLE_COUNT_Y()]; available = new Integer[processes.getAVAILABLE_COUNT_Y()]; //给请求向量赋值 System.out.println("请输入各进程对各类资源分别的请求量:"); for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) { System.out.println("进程" + (i+1)); for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) { System.out.print(processes.getResourceName(j) + ":"); request[i][j] = input.nextInt(); } } //给系统可利用资源向量赋值 System.out.println("请输入各类可利用的资源数目:"); for (int i = 0; i < processes.getAVAILABLE_COUNT_Y(); i++) { System.out.print(processes.getResourceName(i) + ":"); available[i] = input.nextInt(); } //判断资源是否能都满足请求 for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) { System.out.println("进程" + (i+1) + "开始进行请求。。。"); for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) { if (request[i][j] <= processes.getNeedNum(i,j)){ if (request[i][j] <= available[j]){
System.out.println("请求暂时成功,正在进行安全性检查。。。。。。"); //请求暂时成功进行安全性检查
available[j] = available[j] - request[i][j]; processes.setAllocation(i,j,processes.getAllocation(i,j) + request[i][j]); processes.setNeedNum(i,j,processes.getNeedNum(i,j) - request[i][j]); System.out.println("P" + (i+1) + "分配成功!"); break; }else { System.err.println("尚无足够的资源,P" + (i+1) + "需等待"); continue; } }else { System.err.println("请求出错,原因:P" + (i+1) + "进程所需要" + processes.getResourceName(j) + "类资源数已超过它所宣布最大值"); continue; } } System.out.println(); } Safity(processes); }
/** * 安全性算法 */ public void Safity(Processes processes){ Integer[] work = new Integer[processes.getAVAILABLE_COUNT_Y()]; //工作向量Work work = available; String[] finish = new String[processes.getPROCESSES_COUNT()]; //工作向量Finish for (int j = 0; j < finish.length; j++) { finish[j] = "false"; } boolean flag = true; //是否运行完成标志 for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) { for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) { if (finish[i].compareTo("false") == 0 && processes.getNeedNum(i,j) <= work[j]){ work[j] = work[j] + processes.getAllocation(i,j); finish[i] = "true";
}else {
for (int k = 0; k < processes.getPROCESSES_COUNT(); k++) { if (finish[k].compareTo("true") != 0){ flag = false; } } } } }
if (flag) System.out.println("系统处于安全状态"); else System.out.println("系统处于不安全状态"); } }
|
3、创建测试类,调用银行家算法
1 2 3 4 5 6
| public class BankerTest { public static void main(String[] args) { Banker banker = new Banker(); banker.Bank(); } }
|
Author:
Allen Xue
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
To be or not to be,that is a question.