Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)

本文详细介绍银行家算法的数据结构、程序结构及其实现方法,包括银行家算法bank()和安全性算法safe()函数,以及如何通过Java代码模拟程序,检查每个银行客户的请求是否安全,并输出请求和决定的列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


编写银行家算法的模拟程序.
该程序应该能够循环检查每一个提出请求的银行客户并且能判断这一请求是否安全.并把有关请求和相应决定的列表输出.

数据结构介绍:

可利用资源向量     int  Available[m]   m为资源种类
最大需求矩阵       int  Max[n][m]     n为进程的数量
分配矩阵           int  Allocation[n][m] 
还需资源矩阵       int  need[i][j]= Max[i][j]-Allocation[i][j]
申请资源数量       int  Request[m]   
工作向量           int  Work[m], int Finish[n] 

程序结构

程序共有以下五个部分:
(1).初始化init():输入进程数量、资源种类、资源可利用量、进程资源已分配量、进程最大需求量
(2).当前安全性检查safe():用于判断当前状态安全。
(3).银行家算法bank():进行银行家算法模拟实现的模块
(4).显示当前状态show():显示当前资源分配详细情况
(5).主程序main():逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行。

银行家算法bank()函数

Requesti:进程Pi的请求向量。 0<=j<=m-1
(1) 若 Requesti[j] ≤ Need[i,j],转向(2),否则出错。
(2) 若 Requesti[j] ≤ Available[j],转向(3),否则等待。
(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) 试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试探性分配作废,进程Pi等待。

安全性算法safe()函数

(1) 初始化:设置两个向量Work(1×m)和Finish(1×n)
Work – 系统可提供给进程继续运行所需各类资源数,初态赋值Available
Finish – 系统是否有足够资源分配给进程,初值false.
(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 (2).
(4) 若所有进程Finish[i] = true,表示系统处于安全状态,否则处于不安全状态。

Java 代码实现

package com.dhl.beyond.os_bank;

import java.util.Scanner;

public class Bank {
    //数据结构
    int N = 100; //进程的最大数
    int M = 100; //资源的最大数
    String[] Name = new String[100]; //资源的名称
    int[][] Max = new int[100][100];//最大需求矩阵
    int[] Avaliable = new int[100]; //可用资源矩阵
    int[][] Allocation = new int[100][100]; //已经分配资源矩阵
    int[][] Need = new int[100][100];//还需分配资源矩阵
    int[] Request = new int[100];//请求资源向量
    int[] Security = new int[100]; //存放 安全序列
    int[] Work = new int[100]; //存放 系统可提供的资源
    boolean[] Finish = new boolean[50]; //返回是否是安全序列

    //显示资源分配矩阵
    public void showdata() {
        System.out.println("************************************");
        System.out.print("系统目前可用的资源[Avaliable]:\n");
        for (int i = 0; i < M; i++)
            System.out.print(Name[i] + "   ");
        System.out.println(" ");
        for (int j = 0; j < M; j++)
            System.out.printf("%d    ", Avaliable[j]); //输出可用的资源
        System.out.println();
        System.out.println("系统当前的资源分配情况如下:");
        System.out.println("          Max                 Allocation         Need");
        System.out.print("进程名     ");
        for (int j = 0; j < 3; j++) {
            for (int i = 0; i < M; i++) {
                System.out.print(Name[i] + "  "); //打印资源的名称
            }
            System.out.print("           ");
        }
        System.out.println();
        for (int i = 0; i < N; i++) {
            System.out.printf(" P%d       ", i);
            for (int j = 0; j < M; j++) {
                System.out.printf("%d    ", Max[i][j]);
            }
            System.out.print("      ");
            for (int j = 0; j < M; j++) {
                System.out.printf("%d  ", Allocation[i][j]);
            }
            System.out.print("           ");
            for (int j = 0; j < M; j++) {
                System.out.printf("%d  ", Need[i][j]);
            }
            System.out.println();
        }
    }

    //安全性算法
    public int safe() {
        int k = 0;
        for (int j = 0; j < N; j++) {
            Finish[j] = false;
        }
        for (int j = 0; j < M; j++) {
            Work[j] = Avaliable[j];
        }
        for (int i = 0; i < N; i++) {
            int apply = 0;
            for (int j = 0; j < M; j++) {
                if (Finish[i] == false && Need[i][j] <= Work[j]) {
                    apply++;
                    if (apply == M) { //直到找到每种资源都小于 可供利用资源数时才可以进行分配
                        for (int p = 0; p < M; p++) {
                            Work[p] = Work[p] + Allocation[i][p];  //改变  系统可提供的资源值
                        }
                        Finish[i] = true;
                        Security[k] = i;
                        k++;
                        i = -1; //保证每次查询都重第一个进程开始

                    }
                }
            }
        }
        for (int i = 0; i < N; i++) {
            if (Finish[i] == false) {
                System.out.println("系统不安全!");
                return -1;
            }
        }

        System.out.println("系统是安全的!");
        System.out.println("存在一个安全序列如下:");
        for (int i = 0; i < N; i++) {
            System.out.printf("P%d", Security[i]);
            if (i < N - 1)
                System.out.print("-->");
        }
        System.out.println();
        return 0;
    }


    //利用银行家算法对申请资源进行尝试分配
    public void bank() {
        char ch = 'y';
        int allow = 1;
        System.out.printf("请输入请求分配资源的进程号(0-%d):", N - 1);
        Scanner input = new Scanner(System.in);
        int i = input.nextInt();//输入须申请资源的进程号
        System.out.printf("请输入进程P%d要申请的资源个数: \n", i);
        for (int j = 0; j < M; j++) {
            System.out.print(Name[j]+": ");
            Request[j] = input.nextInt(); //输入需要 申请的资源
        }
        for (int j = 0; j < M; j++) {
            if (Request[j] > Need[i][j]) {//判断申请是否大于需求,若大于测出错
                System.out.printf("进程P%d申请的资源大于它需要的资源", i);
                System.out.print("分配不合理,不与分配! \n");
                showdata();
                ch = 'm';
                break;
            } else {
                if (Request[j] > Avaliable[j]) {//判斷申请是否大于当前可分配资源,若大于则出错
                    System.out.printf("进程%d申请的资源大于系统现在可利用的资源", i);
                    System.out.println("");
                    System.out.printf("系统尚无足够资源,不予分配!\n");
                    showdata();
                    System.out.println("");
                    ch = 'm';
                    break;
                } else if (Request[j] > Avaliable[j]) {//判断申请是否大于当前可分配资源,若大于则出错
                    System.out.printf("进程%d申请的资源大于系统现在可利用的资源", i);
                    System.out.println("");
                    System.out.printf("系统向无足够资源,不子分配! \n");
                    showdata();
                    System.out.println("");
                    ch = 'm';
                    break;
                }
            }
        }
        if (ch == 'y') {
            //根据进程等求量变找资源
            for (int j = 0; j < M; j++) {
                Avaliable[j] = Avaliable[j] - Request[j];
                Allocation[i][j] = Allocation[i][j] + Request[j];
                Need[i][j] = Need[i][j] - Request[j];
                showdata();//根据进程需求量显示安换后的资源
                safe();//根据进程需求量进行最行家算法判断


                //如果不安全拒绝分配
                for (int k = 0; k < N; k++) {
                    if (Finish[k] == false) {
                        allow = 0;
                        break;
                    }
                }
            }
            if (allow == 0) {
                for (int j = 0; j < M; j++) {
                    Avaliable[j] = Avaliable[j] + Request[j];
                    Allocation[i][j] = Allocation[i][j] - Request[j];
                    Need[i][j] = Need[i][j] + Request[j];
                }
                System.out.printf("应拒绝P%d的申请,此次尝试分配作废", i);
                System.out.println("");
                System.out.println("还原资源分配矩阵");
                showdata();
            }
        }
    }


    public static void main(String[] args) {
        Bank bank = new Bank();
        int[] temp = new int[100];//每种资源已分配的碧重
        Scanner input = new Scanner(System.in);
        System.out.print("系统可用资源种类个数为:");
        int m = input.nextInt();
        bank.M = m;
        for (int i = 0; i < m; i++) {
            System.out.printf("资源%d的名称:", i+1);
            bank.Name[i] = input.next();
            System.out.print("资源" + bank.Name[i] + "的初始个数为:");
            int number = input.nextInt();
            bank.Avaliable[i] = number;
        }
        System.out.println("");
        System.out.print("证输入进程数目:");
        int n = input.nextInt();
        bank.N = n;
        System.out.print("请输入各进程的最大需求矩阵的值[Max]:\n");
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                bank.Max[i][j] = input.nextInt();
        do {
            boolean flag = false;
            System.out.print("请输入各进程已经分配的资源量[Allocation]:\n");
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++) {
                    bank.Allocation[i][j] = input.nextInt();
                    if (bank.Allocation[i][j] > bank.Max[i][j])
                        flag = true;

                    bank.Need[i][j] = bank.Max[i][j] - bank.Allocation[i][j];
                    temp[j] += bank.Allocation[i][j];
                }
            if (flag == true) {
                System.out.println("申请的资源大于最大需求量。请置新输入!");
                for (int j = 0; j < m; j++)
                    temp[j] = 0; //清空缓神区
                System.out.println("");
            }
        }while(false);
            for (int j = 0; j < m; j++)
                bank.Avaliable[j] = bank.Avaliable[j] - temp[j];//剩下的可用资源
            bank.showdata();//显示各种资源
            bank.safe();//用银行家算法判定系统是否安全
            while (true) {
                System.out.print("**********************************");
                System.out.println("");
                System.out.println("银行家算法:");
                System.out.printf("是否请求分配吗?是请按y/Y,否则请按其它键!\n");
                System.out.println("输入是否请求分配的字符");
                char choice = input.next().charAt(0);
                if (choice == 'y' || choice == 'Y') {
                    bank.bank();
                } else break;
            }
        }
    }




结果测试:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。 设计目的 1)了解多道程序系统中,多个进程并发执行的资源分配。 2)掌握死锁的产生的原因、产生死锁的必要条件和处理死锁的基本方法。 3)掌握预防死锁的方法,系统安全状态的基本概念。 4)掌握银行家算法,了解资源在进程并发执行中的资源分配策略。 5)理解死锁避免在当前计算机系统不常使用的原因 要求: 设计一个n 个并发进程共享m 个系统资源的系统。进程可动态申请资源和释放资源,系统按各进程的申请动态的分配资源。要求采用银行家算法实现。 提示: (1) 初始化这组进程的最大资源请求和依次申请的资源序列。把各进程已占用和需求资源情况记录在进程控制块中。假定进程控制块的内容包括:进程名,状态,当前申请量,资源需求总量,已占资源量,能执行完标志。其中,进程的状态有:就绪、等待和完成。当系统不能满足进程的资源请求时,进程处于等待态。资源需求总量表示进程运行过程中对资源的总的需求量。 已占资源量表示进程目前已经得到但还未归还的资源量。因此,进程在以后还需要的剩余资源量等于资源需要总量减去已占资源量。显然每个进程的资源需求总量不应超过系统拥有的资源总量。 (2) 银行家算法分配资源的原则是:当某个进程提出资源请求时,假定先分配资源给它,然后查找各进程的剩余请求检查系统的剩余资源量是否由于进程的分配而导致系统死锁。若能,则让进程等待,否则,让进程的假分配变为真分配。 a) 查找各进程的剩余请求检查系统的剩余资源量是否能满足其中一进程。如果能,则转b)。 b) 将资源分配给所选的进程,这样,该进程已获得资源最大请求,最终能运行完成。标记这个进程为终止进程,并将其占有的全部资源归还给系统。 重复第a)步和第b)步,直到所有进程都标记为终止进程,或直到一个死锁发生。若所有进程都标记为终止进程,则系统的初始状态是安全的,否则为不安全的。若安全,则正式将资源分配给它,否则,假定的分配作废,让其等待。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_大木_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值