操作系统 银行家算法

银行家算法中的数据结构

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]

银行家算法

设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,并修改下面数据结构中的数值:
Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];
系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程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[i]+Allocation[i,j];
Finish[i]=true;
go to step 2;
4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态

流程图

在这里插入图片描述

java模拟

package System.Bank;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Banker {
    private static Scanner input=new Scanner(System.in);
     int n,m;              //n为进程数,m为资源数
     int Available[];      //可利用资源向量     系统现有j类多少资源



   int Work[];       //工作向量
    boolean Finsh[];      //工作向量

    List<Process> processes=new ArrayList<>();                //进程队列


    public Banker() {
        try {
            init();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void init() throws IOException {
        System.out.println("-----------初始化-------------");
            System.out.print("输入系统资源种类数:");
            int m= input.nextInt();
            Available=new int[m];
            for(int i=0;i<m;i++){
                System.out.print("----输出第"+(i+1)+"类资源的可用资源数目:");
                int number= input.nextInt();
                Available[i]=number;
            }
            System.out.print("输入进程数:");
             n= input.nextInt();
             Finsh=new boolean[n];
           for(int i=0;i<n;i++){
              System.out.println("--创建p"+i+"进程");
              System.out.println("-------设置p"+i+"进程的对"+m+"种资源最大需求:");
              int createMax[]=new int[m];
              for(int j=0;j<m;j++){
                   System.out.print("-----------------对第"+(j+1)+"类资源最大需求:");
                   int number= input.nextInt();
                   createMax[j]=number;
              }
              System.out.println("-------设置To时刻系统对p"+i+"进程的"+m+"种资源的已分配数:");
              int createAllocation[]=new int[m];
              for(int j=0;j<m;j++){
                  System.out.print("-----------------对第"+(j+1)+"类资源已分配数:");
                  int number= input.nextInt();
                   createAllocation[j]=number;
               }
               String name="p"+i;
               Process p=new Process(name,i,createMax,createAllocation);
                processes.add(p);
               CalculateAvailable(p.getAllocation());
           }
        System.out.println("-----------------------t0时刻的资源分配----------------------");
        printProcess();
        System.out.println("------------------------t0时刻资源可利用情况----------");
        print(Available);
        System.out.println("t0时刻资源分配是否安全:"+(isSafe()?"安全":"不安全"));
    }

    private void CalculateAvailable(int Allocation[]){           //计算当前系统可利用资源数
         for(int i=0;i<Allocation.length;i++){
             Available[i]-=Allocation[i];
         }
    }

    public void bank(Process process) throws InterruptedException {            //银行家算法
        int tempAvailable[]=Available;                        //系统可利用资源数
        int Need[]=process.getNeed();                         //此进程的需求数
        int Allocation[]=process.getAllocation();              //此进程的可分配数
        process.Request();                                  //进程请求资源
        int Request[]=process.getRequest();                    //获取请求向量
        for(int j=0;j<Request.length;j++){
            if (Request[j] <= Need[j]) {
                if (Request[j] <= tempAvailable[j]) {
                    tempAvailable[j] = tempAvailable[j] - Request[j];
                    Allocation[j] = Allocation[j] + Request[j];
                    Need[j] = Need[j] - Request[j];
                } else {
                    System.out.println("此进程等待");
                }
            } else {
                System.out.println("出错");
                return;
            }
        }
        if(isSafe()){                 //判断是否安全
            Available=tempAvailable;                        //分配资源
            process.setAllocation(Allocation);
            process.setNeed(Need);
            System.out.println("此次分配安全");
        }else{
            System.out.println("此次分配不安全 ");
            return;
        }
    }


    private boolean isSafe(){              //安全性算法
        Work=Available;
        Arrays.fill(Finsh,false);
        boolean is=true;
        boolean vis[]=new boolean[n];
        List<Process> safeList=new ArrayList<>();//安全队列
        List<Process> tempList=new ArrayList<>();           //临时存储队列
        tempList.addAll(processes);
        Arrays.fill(vis,false);
        Process process=find(tempList);                //找到一个符合的进程
        if(process==null) {                           //如果没有找到,则检查finsh工作向量
            if(check()) {
                  return true;
            }else {
                    return false;
            }
        }
        while (safeList.size()<=n&&process!=null)           //寻找安全序列
        {
                for (int j = 0; j < process.getNeed().length; j++) {
                            Work[j] = Work[j] + process.getAllocation()[j];
                }
                Finsh[process.getId()] = true;
                safeList.add(process);
                tempList.remove(process);
                process=find(tempList);
        }
            if(check()){                  //判断工作向量finish
                System.out.print("安全序列为:");
                for(Process p:safeList){
                    System.out.print(p.getName()+"\t");
                }
                System.out.println();
                return true;
            }else{
                return false;
            }
    }
    private Process find(List<Process> processes ){               //寻找符合条件的进程
        for (int i = 0; i < processes.size(); i++) {
            if(Finsh[processes.get(i).getId()] == false) {
                int j;
                for (j = 0; j < (processes.get(i).getNeed()).length; j++) {
                    if ((processes.get(i).getNeed())[j] > Work[j]) {
                        break;
                    }
                }
                if(j== (processes.get(i).getNeed()).length)
                   return processes.get(i);           //找到则返回此进程
            }
        }
        return null;
    }
    private boolean check(){              //检查系统的finish工作向量
        for(int i=0;i<n;i++){
            if(Finsh[i]==false)
                return false;
        }
        return true;
    }
    public void  printProcess(){             //打印函数
        System.out.println("\t"+"MAX"+"\tAllocationt"+"\tNeed\t");
        for (Process p:processes) {
            StringBuilder str=new StringBuilder();
            str.append(p.getName()+"\t");
            int getMax[]=p.getMax();
            for(int i=0;i<getMax.length;i++){
                str.append(getMax[i]+"\t");
            }
            str.append("\t");

            int getAllocation[]=p.getAllocation();
            for(int i=0;i<getAllocation.length;i++){
                str.append(getAllocation[i]+"\t");
            }
            str.append("\t");
            int getNeed[]=p.getNeed();
            for(int i=0;i<getNeed.length;i++){
                str.append(getNeed[i]+"\t");
            }
            System.out.println(str.toString());
        }
    }

    private void print(int temp[]){     //打印函数
        StringBuilder builder=new StringBuilder();
        for(int i=0;i<temp.length;i++){
             builder.append(temp[i]+"\t");
        }
        System.out.println(builder.toString());
    }
    public Process getProcessById(int id){           //通过进程Id获取当前系统的某一进程
        for(Process p:processes){
            if(p.getId()==id){
                return p;
            }
        }
        return null;
    }


}




class Process{                       //进程的类对象
    private String name;            //进程名
    private int id;                 //进程id
    private int Max[];              //进程的最大需求数
    private int Allocation[];       //进程资源已分配数
    private int Need[];              //进程资源需求数
    private int Request[];           //进程请求向量
    public Process(String name,int id,int[] max, int[] allocation) {
        this.id=id;
        this.name = name;
        this.Max = max;
        this.Allocation = allocation;
        Need=new int[Max.length];
        Request=new int[Max.length];
        for(int i=0;i<Max.length;i++){
            Need[i]=Max[i]-Allocation[i];
        }
    }
    public Process() {
    }
    public void setRjMax(int j, int k){
        Max[j]=k;
    }
    public  void setRjAllocation(int j,int k){
        Allocation[j]=k;
        Need[j]=Max[j]-Allocation[j];
    }

    public int[] getMax() {
        return Max;
    }

    public void setMax(int[] max) {
        Max = max;
    }

    public int[] getAllocation() {
        return Allocation;
    }

    public void setAllocation(int[] allocation) {
        Allocation = allocation;
    }

    public int[] getNeed() {
        return Need;
    }

    public void setNeed(int[] need) {
        Need = need;
    }


    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public int[] getRequest() {
        return Request;
    }

    public void Request() {                //请求向量的函数
        Scanner input=new Scanner(System.in);
        System.out.println("输入请求量:");
        for(int i=0;i<Request.length;i++) {
            System.out.print("第"+(i+1)+"类资源的请求量:");
            int number=input.nextInt();
            Request[i]=number;
        }
    }
}



public class Main {
    static Scanner input=new Scanner(System.in);
    public static void main(String[] args) throws Exception {
            Banker banker=new Banker();
            System.out.print("输入要请求资源的进程id:");
            int id=input.nextInt();
            Process process=banker.getProcessById(id);
            if(process!=null) {
                System.out.println(process.getName() + "  " + process.getId());
                banker.bank(process);
            }else {
                System.out.println("没有此进程");
            }
        }
}

执行结果:


-----------初始化-------------
输入系统资源种类数:3
----输出第1类资源的可用资源数目:10
----输出第2类资源的可用资源数目:5
----输出第3类资源的可用资源数目:7
输入进程数:5
--创建p0进程
-------设置p0进程的对3种资源最大需求:
-----------------对第1类资源最大需求:7
-----------------对第2类资源最大需求:5
-----------------对第3类资源最大需求:3
-------设置To时刻系统对p0进程的3种资源的已分配数:
-----------------对第1类资源已分配数:0
-----------------对第2类资源已分配数:1
-----------------对第3类资源已分配数:0
--创建p1进程
-------设置p1进程的对3种资源最大需求:
-----------------对第1类资源最大需求:3
-----------------对第2类资源最大需求:2
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p1进程的3种资源的已分配数:
-----------------对第1类资源已分配数:2
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:0
--创建p2进程
-------设置p2进程的对3种资源最大需求:
-----------------对第1类资源最大需求:9
-----------------对第2类资源最大需求:0
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p2进程的3种资源的已分配数:
-----------------对第1类资源已分配数:3
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:2
--创建p3进程
-------设置p3进程的对3种资源最大需求:
-----------------对第1类资源最大需求:2
-----------------对第2类资源最大需求:2
-----------------对第3类资源最大需求:2
-------设置To时刻系统对p3进程的3种资源的已分配数:
-----------------对第1类资源已分配数:2
-----------------对第2类资源已分配数:1
-----------------对第3类资源已分配数:1
--创建p4进程
-------设置p4进程的对3种资源最大需求:
-----------------对第1类资源最大需求:4
-----------------对第2类资源最大需求:3
-----------------对第3类资源最大需求:3
-------设置To时刻系统对p4进程的3种资源的已分配数:
-----------------对第1类资源已分配数:0
-----------------对第2类资源已分配数:0
-----------------对第3类资源已分配数:2
-----------------------t0时刻的资源分配----------------------
	MAX	Allocationt	Need	
p0	7	5	3		0	1	0		7	4	3	
p1	3	2	2		2	0	0		1	2	2	
p2	9	0	2		3	0	2		6	0	0	
p3	2	2	2		2	1	1		0	1	1	
p4	4	3	3		0	0	2		4	3	1	
------------------------t0时刻资源可利用情况----------
3  3  2	
安全序列为:p1      p3   p0  p2  p4	
t0时刻资源分配是否安全:安全
输入要请求资源的进程id:1
p1  1
输入请求量:
第1类资源的请求量:12类资源的请求量:03类资源的请求量:2
安全序列为:p0    p1  p2	p3  p4	
此次分配安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值