admin管理员组

文章数量:1531793

0、资源链接:csdn资源下载

一、 设计要求

设计一个n个并发进程共享m个系统资源的程序以实现银行家算法。要求:
1) 简单的选择界面;
2) 能显示当前系统资源的占用和剩余情况。
3) 为进程分配资源,如果进程要求的资源大于系统剩余的资源,不与分配并且提示分配不成功;
4) 撤销作业,释放资源。
编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁的发生。

二、 运行环境

此程序运行于Java 16.0.2 环境中,在windows系统

三、 系统功能

模拟银行家算法程序,模拟防止不当的系统资源分配造成死锁。由于图形化界面需求显示无限资源种类无限进程数量较为困难,所以图形化程序只完成了三种系统资源和十个进程调度的编写。如果需要无限资源种类和无限进程数量,可以稍微修改一下工程代码即可实现,因为命令行程序代码有保留在工程的注释中。
用户使用程序前需要设置系统各类资源的最大值以及添加各类进程的初始信息(进程ID、进程各类资源最大需求量)。之后用户即可以对进程进行资源分配,系统会根据分配后的状态安全检查判定是否能进行本次分配,如果可以则分配成功且给出一种安全序列,如果会造成死锁则提醒用户更正错误。在进程得到了所有需求资源后会显示进程已完成并释放进程所占用的各类资源。
该程序能够显示每个进程的信息(进程ID、进程各类所需的最大资源量、进程已分配的资源量、进程还需的资源量、进程是否已经完成)以及系统总资源和剩余总资源。

四、 所有数据结构

public static int n = 0;//系统中进程总数n
    public static int m = 0;//系统中资源种类总数m
    public static int[] aMax = new int[3];//图形化用保存最大系统资源总量
    public static int[] Available = new int[100];//系统资源可用资源量
    public static int[][] Max = new int[100][100];//进程最大需求资源矩阵
    public static int[][] Allocation = new int[100][100];//当前已分配给进程的各种资源数量
    public static int[][] Need = new int[100][100];//当前每个进程还需分配的各种资源数量
    public static int[] Work = new int[100];//当前系统剩余可分配的资源
    public static boolean[] Finish = new boolean[100];//进程是否已完成
    public static int[] result = new int[101];//结果
    public static int[] request = new int[100];//需求
    public static int flag = 0;//存放请求分配时发生事件的类型有1、2、3、4

五、 主要函数功能

  1. 判断是不是所有进程均已执行完
public static boolean judge_end(boolean[] f) {
        boolean flag = true;
        for(int i=0;i<main.m;i++) {
            if (!f[i]) {
                flag = false;
                break;
            }
        }
        return flag;
}
  1. 系统状态安全检查
public static void safety() {
        //复制初始化Work
        for(int i=0;i<main.m;i++) {
            main.Work[i] = main.Available[i];
        }
        //复制初始化finish
        boolean[] finish = new boolean[100];
        for(int i=0;i<main.n;i++) {
            finish[i] = main.Finish[i];
        }
        int count = 1;
        int flag1 = 0;
        int flag2 = 1;
        for(int i=0;i<main.n;i++) {
            if (i == 0)
                flag1 = 0;
            //跳过已经完成的进程
            if (finish[i] == true)
                continue;
            //Work与Need比较
            int flag3 = 1;
            for(int j=0;j<main.m;j++) {
                if (main.Work[j] < main.Need[i][j]) {
                    flag3 = 0;
                    break;
                }
            }
            //若资源不够则跳过这一进程
            if (flag3 != 1) {
                //是不是本次循环进程一个都没能结束
                if (i == main.n - 1 && flag1 != 1){
                    //分析一个都没能结束的原因
                    //是不是全部进程已经都执行完了
                    if (judge_end(finish))
                        break;
                    else{
                        //存在没结束的进程但无法结束
                        flag2 = 0;
                        break;
                    }
                }
                continue;
            } else {
                //若资源够,则执行完该进程,释放该进程占用的资源
                main.result[count] = i;
                count++;
                for (int j = 0; j < main.m; j++){
                    main.Work[j] = main.Work[j] + main.Allocation[i][j];
                }
                finish[i] = true;
                flag1 = 1;//标记这一轮找到了可以执行完的进程
                i = -1;//从头再开始遍历进程集合
            }
        }
        main.result[0] = flag2;
}
  1. 请求资源分配
public static boolean allocate(int num){
        int flag = 1;
        for (int i = 0; i < main.m; i++){
            if (main.request[i] > main.Need[num][i]){
                flag = 0;
                break;
            }
        }
        if (flag == 0){
            main.flag = 1;		//图形化界面需求
            System.out.println("请求大于该进程还需要的资源量,请求不合法");
            return false;
        }
        for (int i = 0; i < main.m; i++){
            if (main.request[i] > main.Available[i]){
                flag = 0;
                break;
            }
        }
        if (flag == 0){
            main.flag = 2;		//图形化界面需求
            System.out.println("请求大于当前系统剩余的资源量,请求不合法");
            return false;
        }

        // 尝试分配
        for (int i = 0; i < main.m; i++){
            main.Need[num][i] = main.Need[num][i] - main.request[i];
            main.Allocation[num][i] = main.Allocation[num][i] + main.request[i];
            main.Available[i] = main.Available[i] - main.request[i];
        }

        //分配后的安全性判断,会生成安全序列
        Arrays.fill(main.result,-1);
        safety();
        if (main.result[0] == 1){
            main.flag = 3;		//图形化界面需求
            System.out.print("存在此安全序列:");
            for (int i = 1;main.result[i] != -1; i++){
                System.out.print("P" + main.result[i]);
            }
            System.out.println("");
            return true;
        }else{
             main.flag = 4;	//图形化界面需求
            System.out.println("根据安全性检查,本次分配不安全");
            //撤销分配
            for (int i = 0; i < main.m; i++){
                main.Need[num][i] = main.Need[num][i] + main.request[i];
                main.Allocation[num][i] = main.Allocation[num][i] - main.request[i];
                main.Available[i] = main.Available[i] + main.request[i];
            }
            return false;
        }
}
  1. 判定进程是否已完成,已完成则释放资源
public static void end(int num) {

        int flag = 1;
        for (int i = 0; i < main.m; i++){
            if (main.Need[num][i] > 0){
                flag = 0;
                break;
            }
        }
        //释放资源
        if (flag == 1){
            System.out.println("进程P"+ num + "执行完成");
            main.Finish[num] = true;
            for (int i = 0; i < main.m; i++){
                main.Available[i] = main.Available[i] + main.Allocation[num][i];
                main.Allocation[num][i] = 0;
            }
        }
}
  1. 图形化界面代码
    代码里同样有属于图形化程序的重要代码存在,但由于报告篇幅,不进行剪贴,可在工程内查看

六、 运行情况

  1. 设置系统资源


2. 添加进程信息

  1. 请求分配资源成功


  2. 请求资源大于进程还需资源时

  3. 请求资源大于系统剩余资源时

  4. 请求会造成死锁时,观察当前系统之所以还安全是因为仍可以满足P1和P2进程完成,以至于释放资源。如果进程P4将它们要求的C资源全部请求分配掉,系统剩余A:0,B:1,C:0,则此时系统将会不安全,不存在安全序列,进入死锁,所以阻止请求

0、资源链接:csdn资源下载

本文标签: 银行家算法图形化操作系统程序