//2020.5.12
银行家算法 在操作系统中是一个非常典型 且重要的算法
1: 银行家算法目的:由迪杰斯特拉所创造的 避免死锁 的著名算法。
2:产生的根源:此算法一银行借贷系统的分配策略为基础,以此保证系统的安全运行。假如把操作系统看做银行家,操作系统管理的资源相当于银行里资金,进程想操作系统请求分配资源就是用户向银行家贷款。、
3:银行家算法数据结构:
(1) int Availavble[100]={0} //系统可用资源
有m个元素的数组, 其中的每一个元素代表一类可利用的资源数目,
如果Available[j]=k 表示系统中有j类资源k个。
(2) int Max[100] [100]={0} //各进程所需资源的最大需求 最大需求矩阵Max
这代表一个n*m的矩阵, 他定义了系统中n个进程中每一个进程对m类资源的最大需求。
如果Max[i][j]=k, 表示进程i 需要j类资源的最大数目为k。
(3)int Allocation【100】【100】={0} //系统已分配的资源 分配矩阵Allocation
这代表一个n*m的矩阵,定义为系统中每一类资源当前已分配给每一个进程的资源
如果Allocation【i】【j】= 表示进程i当前已分配j类资源的数目为k。
(4) int Need[100][100] ={0} //还需要资源 需要矩阵Need
这代表n*m'的矩阵, 用以表示每一个进程尚需各类资源数,如果Need【i】【j】=k;
这表示进程i还需要j类资源k个,然能完成任务。
***Need[i] [j]=Max[i] [j] - Allocation[i] [j]. 很重要。
4:银行家算法 系统检查步骤:
假如Requesti是进程pi的请求量,如果Requesti[j] = k,表示进程pi 需要k个j类型资源 ,果进程发出资源请求
(1)如果 Requesti [j] <=Need [i][j] 转到第(2)部, 否则出错, 因它所需要的资源数已还需要的最大值。
(2)如果Requesti [j] <=Available[j] 转第三部, 否则出错, 因系统表示没有足够的资源,进程需要等待。
(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)安全算法系统所执行的安全算法可描述如下:
<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 都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
5:下面分别是测试类和银行家算法功能类;
测试类:
package Bank;
import java.util.Scanner;
public class TestBanker {
public static void main(String[] args) {
boolean Choose = true;
String C;
Scanner input = new Scanner(System.in);
Banker bank = new Banker();
System.out.println("这是三个进程,初始系统可用三类资源为{10,8,7}的银行家算法");
bank.setSystemVariable();
while (Choose == true) {
bank.setRequest();
System.out.println("是否还要进行请求:y/n");
C = input.nextLine();
if (C.endsWith("n")) {
Choose = false;
}
}
}
}
package Bank;
import java.util.Scanner;
public class Banker {
int Available[] = { 10, 8, 7, }; // 可提供
int Max[][] = new int[3][3]; // 最大需求
int Allocation[][] = new int[3][3]; // 已分配
int Need[][] = new int[3][3]; // 还需要
int Requesti[][] = new int[3][3];
int work[] = new int[3];
int num = 0; // 进程编号
Scanner input = new Scanner(System.in);
// 设置各种初始系统变量, 并且判断是否处于安全状态
public void setSystemVariable() {
setMax();
setAllocation();
printSystemVariable();
SecurityAlorithm();
}
// 设置Max矩阵
public void setMax() {
System.out.println("请设置各进程最大需求矩阵Max:");
for (int i = 0; i < 3; i++) {
System.out.println("请输入进程p" + i + "的最大需求资源需求量:");
for (int j = 0; j < 3; j++) {
Max[i][j] = input.nextInt();
}
}
}
// 设置已分配矩阵Allocation
public void setAllocation() {
System.out.println("请设置各进程已分配矩阵Allocation:");
for (int i = 0; i < 3; i++) {
System.out.println("请输入进程p" + i + "的分配资源量:");
for (int j = 0; j < 3; j++) {
Allocation[i][j] = input.nextInt();
}
}
System.out.println("Available=Available-Alloction.");
System.out.println("Need=Max-Alloction.");
for (int i = 0; i < 3; i++) {// 设置Alloction矩阵
for (int j = 0; j < 3; j++) {
Available[i] = Available[i] - Allocation[j][i];
}
}
for (int i = 0; i < 3; i++) {// 设置Need矩阵
for (int j = 0; j < 3; j++) {
Need[i][j] = Max[i][j] - Allocation[i][j];
}
}
}
public void printSystemVariable() {
System.out.println("此时资源分配量如下:");
System.out.println("进程 " + " Max " + " Alloction " + " Need " + " Available ");
for (int i = 0; i < 3; i++) {
System.out.print("P" + i + " ");
for (int j = 0; j < 3; j++) {
System.out.print(Max[i][j] + " ");
}
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(Allocation[i][j] + " ");
}
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(Need[i][j] + " ");
}
System.out.print("| ");
if (i == 0) {
for (int j = 0; j < 3; j++) {
System.out.print(Available[j] + " ");
}
}
System.out.println();
}
}
public void setRequest() {// 设置请求资源量Request
System.out.println("请输入请求资源的进程编号:");
num = input.nextInt();// 设置全局变量进程编号num
System.out.println("请输入请求各资源的数量:");
for (int j = 0; j < 3; j++) {
Requesti[num][j] = input.nextInt();
}
System.out.println("即进程P" + num + "对各资源请求Request:(" + Requesti[num][0] + "," + Requesti[num][1] + ","
+ Requesti[num][2] + ").");
BankerAlgorithm();
}
public void BankerAlgorithm() {// 银行家算法
boolean T = true;
if (Requesti[num][0] <= Need[num][0] && Requesti[num][1] <= Need[num][1] && Requesti[num][2] <= Need[num][2]) {// 判断Request是否小于Need
if (Requesti[num][0] <= Available[0] && Requesti[num][1] <= Available[1]
&& Requesti[num][2] <= Available[2]) {// 判断Request是否小于Alloction
for (int i = 0; i < 3; i++) {
Available[i] -= Requesti[num][i];
Allocation[num][i] += Requesti[num][i];
Need[num][i] -= Requesti[num][i];
}
} else {
System.out.println("当前没有足够的资源可分配,进程P" + num + "需等待。");
T = false;
}
} else {
System.out.println("进程P" + num + "请求已经超出最大需求量Need.");
T = false;
}
if (T == true) {
printSystemVariable();
System.out.println("现在进入安全算法:");
SecurityAlorithm();
}
}
// 安全算法
public void SecurityAlorithm() {
boolean[] Finish = { false, false, false }; // 初始化
int count = 0; // 完成进程数
int circle = 0; // 循环圈数
int[] S = new int[3]; // 安全序列
for (int i = 0; i < 3; i++) { // 设置工作向量
work[i] = Available[i];
}
boolean flag = true;
while (count < 3) {
if (flag) {
System.out.println("进程 " + " work " + " Allocation " + " Need " + " Work+Allocation");
flag = false;
}
for (int i = 0; i < 3; i++) {
if (Finish[i] == false && Need[i][0] <= work[0] && Need[i][1] <= work[1] && Need[i][2] <= work[2]) {// 判断条件
System.out.print("p" + i + " ");
for (int k = 0; k < 3; k++) {
System.out.print(work[k] + " ");
}
System.out.print("| ");
for (int j = 0; j < 3; j++) {
work[j] += Allocation[i][j];
}
Finish[i] = true; // 当当前进程能满足时
S[count] = i;// 设置当前序列排号
count++;// 瞒住进程数加一
for (int j = 0; j < 3; j++) {
System.out.print(Allocation[i][j] + " ");
}
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(Need[i][j] + " ");
}
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(work[j] + " ");
}
System.out.println();
}
}
circle++; // 循环圈数加一
if (count == 3) {// 判断是否满足所有进程需要
System.out.print("此时存在一个安全序列:");
for (int i = 0; i < 3; i++) {
System.out.print("p" + S[i] + " ");
}
System.out.println("故当前可分配!");
break;
}
if (count < circle) {
count = 5;
System.out.println("当前系统处于不安全状态,故不存在安全序列。");
break;
}
}
}
}
6;测试截图:
7:
【实验体会】
体会: 当初老师讲银行家算法时,处于半懂状态,只了解“最大需求Max”“已分配Alloction”“还需要Need”“可提供Available”之间的关系,以及存在安全序列,可以进行资源分布的条件,Request<=Need及Request<=Available.但也不是很懂如何用代码实现,后来经过查阅资料,其实也就是数组经过for循环储存及相关计算。