银行家算法

银行家算法

一、死锁

  • 定义:死锁是指两个或两个以上的进程在执行中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都无法推进下去,此时称系统处于死锁状态或系统产生了死锁。

  • 死锁的产生:

    • 1):各进程竞争有限的资源;
    • 2):进程之间的顺序推进不当。
  • 死锁发生的必要条件是:

    • 互斥条件
    • 保持和等待条件
    • 不可剥夺条件
    • 环路等待条件
  • 死锁的避免——银行家算法

  • 死锁预防的方法:

    • (1)摈弃“请求和保持”条件,就是如果系统有足够资源,便一次性把进程需要的所有资源分配给它;
    • (2)摈弃“不剥夺”条件,就是已经拥有资源的进程,当它提出新资源请求而不能立即满足时,必须释放它已保持的所有资源,待以后需要时再重新申请;
    • (3)摈弃“环路等待”条件,就是将所有资源按类型排序标号,所有进程对资源的请求必须严格按序号递增的次序提出。

二、银行家算法的数据结构

  • 可利用资源组(available)
  • 进程最大需求矩阵(max)
  • 分配矩阵(allocation)
  • 需求矩阵(need)

                          
    need(i,j) = max(i,j) - allocation(i,j)
                          
                        

三、银行家算法

  • (1) 如果 Request i[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源 数已超过它所宣布的最大值。
  • (2) 如果 Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi 须 等待。
  • (3) 系统试探着把资源分配给进程 P i,并修改下面数据结构中的数值:

                            
    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]; 
                            
                          
  • (4) 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正 式将资源分配给进程 Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资 源分配状态,让进程 Pi等待。

四、安全性算法

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

  • (1) 设置两个向量:
    • ① 工作向量 Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有 m 个元素,在执行安全算法开始时,Work = Available。
    • ② Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做 Finish[i] = 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 step 2; 
                            
                          
  • (4) 如果所有进程的 Finish[i]=true 都满足,则表示系统处于安全状态;否则,系统处于 不安全状态。

五、实现代码

                    
package com.edu.bank;

import java.util.Scanner;

public class BankAlgorithm {
    //系统可用资源数
    private Integer[] available;
    //M个进程对N类资源最大资源需求量
    private Integer[][] max;
    //M个进程已经得到N类资源的资源量
    private Integer[][] allocation;
    //M个进程还需要N类资源的资源量
    private Integer[][] need;

    public void setMax(Integer[][] max) {
        this.max = max;
    }

    public void setAllocation(Integer[][] allocation) {
        this.allocation = allocation;
    }

    //计算需求资源(need)
    public void countNeed(){
        need = new Integer[max.length][max[0].length];
        for (int i=0;i<max.length;i++){
            for (int j=0;j<max[i].length;j++){
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }
    }
    //计算系统可用资源数(available)
    public void countAvailable(Integer[] allResources){
        available = new Integer[allResources.length];
        for (int i=0;i<allocation.length;i++){
            for(int j=0;j<allocation[i].length;j++){
                //减去已经被占据的资源
                available[j] = allResources[j] - allocation[i][j];
                if (available[j]<0){
                    available[j] = 0;
                }
                allResources[j] = available[j];
            }
        }
    }

    //分配资源
    private void changdata(Integer[] request,Integer index){
        for (int i=0;i<request.length;i++){
            available[i] = available[i] - request[i];
            allocation[index][i] = allocation[index][i] + request[i];
            need[index][i] = need[index][i] - request[i];
        }
    }
    //恢复现场
    private void rstordata(Integer[] request,Integer index){
        for (int i=0;i<request.length;i++){
            available[i] = available[i] + request[i];
            allocation[index][i] = allocation[index][i] - request[i];
            need[index][i] = need[index][i] + request[i];
        }
    }
    //检查安全性
    public Boolean checkSecurity(){
        Integer[] process = new Integer[need.length];
        Integer[] work = new Integer[available.length];

        Boolean[] finish = new Boolean[need.length];
        Boolean flag = false;
        int index = 0;
        for (int i=0;i<available.length;i++){
            work[i] = available[i];
        }

        for (int i=0;i<need.length;i++){
            for (int j=0;j<need.length;j++){
                Boolean[] security = new Boolean[available.length];
                //判断该进程是否已检验过
                if (null!=finish[j]){
                    continue;
                }
                for (int k=0;k<need[j].length;k++){
                    if (work[k]>=need[j][k]){
                        security[k] = true;
                    }else {
                        continue;
                    }
                }
                Boolean mark = false;
                for(int n=0;n<security.length;n++){
                    if (null!=security[n]&&security[n]){
                        mark = true;
                    }else {
                        mark = false;
                        break;
                    }
                }
                if (mark){
                    for (int q=0;q<work.length;q++){
                        work[q] = work[q] + allocation[j][q];

                        System.out.print(work[q] + " ");
                    }
                    System.out.println();

                    finish[j] = true;
                    process[index++] = j;
                }
            }
        }
        for (int i=0;i<finish.length;i++){
            if (null!=finish[i]){
                flag = true;
            }else {
                flag = false;
            }
        }
        if (flag){
            System.out.print("安全序列为:");
            for (int i=0;i<process.length;i++){
                System.out.print("P" + process[i] + " ");
            }
            System.out.println();
        }else {
            System.out.println("该序列不安全!");
        }

        return flag;
    }

    //银行家算法
    public Boolean bankerAlgorithm(Integer[] request,Integer index){
        Boolean needFlag = false;
        Boolean availableFlag = false;
        for (int i=0;i<request.length;i++){
            if (need[index][i]>=request[i]){
                needFlag = true;
            }else {
                System.out.println("进程P" + index + "申请的资源数大于进程P" + index + "还需要" + i + "类资源的资源量!");
                return false;
            }
        }
        if (needFlag){
            for (int i=0;i<request.length;i++){
                if (available[i]>=request[i]){
                    availableFlag = true;
                }else {
                    System.out.println("进程P" + index + "申请的资源数大于系统可用" + i + "类资源的资源量");
                    return false;
                }
            }
            if (availableFlag){
                changdata(request,index);
                Boolean security = checkSecurity();
                if (security){
                    //安全
                    return true;
                }else {
                    rstordata(request,index);
                }
            }
        }
        return false;
    }
    //展示数据
    public void showData(){
        System.out.print("系统目前各资源可用数目为(available):[");
        for (int i=0;i<available.length;i++){
            System.out.print(available[i] + " ");
        }
        System.out.println("]");
        System.out.println("资源请求进程   最大需求量矩阵     已分配资源       需求资源");
        for (int i=0;i<max.length;i++){
            System.out.print("\t P" + i + "\t\t\t");
            for (int j=0;j<max[i].length;j++){
                System.out.print(max[i][j] + "\t");
            }
            System.out.print("\t");
            for (int j=0;j<allocation[i].length;j++){
                System.out.print(allocation[i][j] + "\t");
            }
            System.out.print("\t");
            for (int j=0;j<need[i].length;j++){
                System.out.print(need[i][j] + "\t");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        //各种资源的数目总和
        Integer allResources[] = {10,5,7};
        //M个进程对N类资源最大资源需求量
        Integer max[][] = {{7,5,3},
                {3,2,2},
                {9,0,2},
                {2,2,2},
                {4,3,3}};
        //M个进程已经得到N类资源的资源量
        Integer allocation[][] = {{0,1,0},
                {2,0,0},
                {3,0,2},
                {2,1,1},
                {0,0,2}};
        Integer request[] = new Integer[allResources.length];
        Integer index;
        Character flag;

        BankAlgorithm bank = new BankAlgorithm();
        bank.setMax(max);
        bank.setAllocation(allocation);
        bank.countAvailable(allResources);
        bank.countNeed();
        bank.showData();
        bank.checkSecurity();
        Scanner input = new Scanner(System.in);
        do {
            do {
                System.out.print("请输入请输入需申请资源的进程号(从P0到P" + (max.length-1) + ",否则重输入!)P");
                index = input.nextInt();
                System.out.println();
            }while (index<0||index>=max.length);
            System.out.println("请输入进程P" + index + "申请的资源数:");
            for (int i=0;i<request.length;i++){
                System.out.print("资源" + i + ":");
                request[i] = input.nextInt();
                System.out.println();
            }

            bank.bankerAlgorithm(request,index);
            bank.showData();
            System.out.println("是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示:");
            flag = input.next().charAt(0);
        }while (flag=='y'||flag=='Y');
    }
}
                  
                

Reprint please specify: sunnyandgood Hello World