银行家算法

举报
俺想吃蜂蜜 发表于 2022/04/06 20:26:18 2022/04/06
【摘要】 银行家算法银行家算法是一个用来避免死锁的算法。下面我们通过一个例题来解释怎么使用 实例假定系统中有五个进程{P0、P1、P2、P3、P4}和三种类型资源{A、B、C},每一种资源的数量分别为10、5、7。各进程的最大需求、T0时刻资源分配情况如下 所示。试问:一、T0时刻是否安全?二、T0之后的T1时刻P1请求资源Request1(1,0,2)是否允许?三、T1之后的T2时刻P4请求资源R...

银行家算法

银行家算法是一个用来避免死锁的算法。
下面我们通过一个例题来解释怎么使用

实例

假定系统中有五个进程{P0、P1、P2、P3、P4}和三种类型资源{A、B、C},每一种资源的数量分别为10、5、7。各进程的最大需求、T0时刻资源分配情况如下 所示。
image.png

试问:
一、T0时刻是否安全?

二、T0之后的T1时刻P1请求资源Request1(1,0,2)是否允许?

三、T1之后的T2时刻P4请求资源Request4(3,3,0)是否允许?

四、T2之后的T3时刻P0请求资源Request0(0,2,0)是否允许?
解:一、T0时刻是否安全?
工作向量Work.它表示系统可提供给进程继续运行所需要的各类资源的数目
(1) T0时刻安全性分析
image.png

存在安全序列{P1, P3, P0, P2, P4},系统安全。
二、T0之后的T1时刻P1请求资源Request1(1,0,2)可否允许?
① Request1(1,0,2) ≤ Need1(1,2,2),P1请求在最大需求范围内;
② Request1(1,0,2) ≤ Available1(3,3,2),可用资源可满足P1请求需要;
③ 假定可为P1分配,修改Available,Allocation1,Need1向量。 Available(2,3,0) = Available(3,3,2)-Request1(1,0,2); Need1(0,2,0) = Need1(1,2,2)-Request1(1,0,2); Allocation1(3,0,2) =Allocation1(2,0,0)+Request1(1,0,2);
④ 利用安全性算法检查试探将资源分配后状态的安全性
image.png

存在安全序列{P1, P3, P0, P2, P4},所以试探将资源分配给进程P1后的状态是安全的,可将资源分配给进程P1。
三、
T1之后的T2时刻P4请求资源Request4(3,3,0)是否允许?
Request4(3,3,0)≤Need4(4,3,1),P4请求在最大需求范围内。 Request4(3,3,0)≤Available(2,3,0)不成立,即可用资源暂不能满足P4请求资源需要,P4阻塞等待。 P4请求资源Request4(3,3,0)不允许。
四、
T2之后的T3时刻P0请求资源Request0(0,2,0)是否允许?
Request0(0,2,0)≤Need0(7,4,3); Request0(0,2,0)≤Available(2,3,0); 系统暂时先假定可为P0分配资源,并修改有关数据,如下图所示。
image.png

进行安全性检查:可用资源Available(2,1,0)已不能满足任何进程的需要,故系统进入不安全状态,此时系统不分配资源。 如果在银行家算法中,把P0发出的请求向量改为Request0(0,1,0),系统是否能将资源分配给它,请考虑。
程序代码如下
`package com.lzl.bank;

import java.util.Scanner;

public class BankerClass {

int[] Available = {10, 8, 7};
int[][] Max = new int[3][3];
int[][] Alloction = new int[3][3];
int[][] Need = new int[3][3];
int[][] Request = new int[3][3];
int[] Work = new int[3];

int num = 0;//进程编号
Scanner in = new Scanner(System.in);

public BankerClass() {
    // Max={{6,3,2},{5,6,1},{2,3,2}};

}
public void setSystemVariable(){//设置各初始系统变量,并判断是否处于安全状态。
    setMax();
    setAlloction();
    printSystemVariable();
    SecurityAlgorithm();
}

public void setMax() {//设置Max矩阵
    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] = in.nextInt();
        }
    }
}

public void setAlloction() {//设置已分配矩阵Alloction
    System.out.println("请设置请各进程分配矩阵Alloction:");
    for (int i = 0; i < 3; i++) {
        System.out.println("晴输入进程P" + i + "的分配资源量:");
        for (int j = 0; j < 3; j++) {
            Alloction[i][j] = in.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] - Alloction[j][i];
        }
    }
    for (int i = 0; i < 3; i++) {//设置Need矩阵
        for (int j = 0; j < 3; j++) {
            Need[i][j] = Max[i][j] - Alloction[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(Alloction[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= in.nextInt();//设置全局变量进程编号num
    System.out.println("请输入请求各资源的数量:");
    for (int j = 0; j < 3; j++) {
        Request[num][j] = in.nextInt();
    }
    System.out.println("即进程P" + num + "对各资源请求Request:(" + Request[num][0] + "," + Request[num][1] + "," + Request[num][2] + ").");

    BankerAlgorithm();
}

public void BankerAlgorithm() {//银行家算法
    boolean T=true;

    if (Request[num][0] <= Need[num][0] && Request[num][1] <= Need[num][1] && Request[num][2] <= Need[num][2]) {//判断Request是否小于Need
        if (Request[num][0] <= Available[0] && Request[num][1] <= Available[1] && Request[num][2] <= Available[2]) {//判断Request是否小于Alloction
            for (int i = 0; i < 3; i++) {
                Available[i] -= Request[num][i];
                Alloction[num][i] += Request[num][i];
                Need[num][i] -= Request[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("现在进入安全算法:");
    SecurityAlgorithm();
   }
}


public void SecurityAlgorithm() {//安全算法
    boolean[] Finish = {false, false, false};//初始化Finish
    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  "+"   Alloction "+"    Need  "+"     Work+Alloction ");
            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]+=Alloction[i][j];
                }
                Finish[i]=true;//当当前进程能满足时
                S[count]=i;//设置当前序列排号

                count++;//满足进程数加1
                for(int j=0;j<3;j++){
                   System.out.print(Alloction[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++;//循环圈数加1

        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;//跳出循环
        }
    }
}

}`

测试代码
`package com.lzl.bank;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class ProcessToo {
public String name;// 进程名
public int run;// 已经运行的时间

public ProcessToo(String name, int run, int needtime) {
this.name = name;
this.run = run;
this.needtime = needtime;
}

public int needtime;// 所需要的时间

}

public class Test1 {

public static void main(String[] args) {
List<String> listname=new ArrayList<>();//记录淘汰的进程名
List<Integer> listtime=new ArrayList<>();//记录淘汰的进程的淘汰时间
int cputime = 0;// CPU运行时间

Scanner in = new Scanner(System.in);
System.out.println("请输入进程个数:");
int n = in.nextInt();
String name;
int ttime;
int needtime;
List<ProcessToo> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
    System.out.println("请输入第"+(i+1)+"进程名:");
    name = in.next();
    System.out.println("请输入第"+(i+1)+"运行时间:");
    needtime = in.nextInt();
    ProcessToo pcb = new ProcessToo(name, 0, needtime);// 运行时间初始化为0
    list.add(pcb);
}

for (int i = 0; i < list.size(); i++) {
    cputime++;
    System.out.println("CPU时刻:" + cputime);
    System.out.println("正在运行的进程:"+list.get(i).name);
    System.out.println("Name   run  req  status");
    list.get(i).run++;//当前进程的运行时间+1
    for(int j = 0;j <list.size();j ++) {
    System.out.print(list.get(j).name+"   "+list.get(j).run+"   "+list.get(j).needtime+"   ");
    System.out.println(list.get(j).run==list.get(j).needtime?"E":"R");
    }
    if(list.get(i).needtime==list.get(i).run) {
    listtime.add(cputime);
    listname.add(list.get(i).name);
    list.remove(i);
    i--;
    }else {
    if (i == (list.size() - 1)) {
        i = -1;
        }
    }
}
for(int i =0;i < n;i ++) {
    System.out.println(listname.get(i)+"的周转时间:"+listtime.get(i)+"ms");
}

}

}`
运行结果如下
image.png

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。