操作系统--银行家算法实现

351 阅读2分钟

最近正在上操作系统的课程,有道课后作业题如下

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

首先翻看课本,找到银行家算法的基本步骤

  • 循环判断:
  • 1、查找是否有进程的需求资源数 小于等于可用的资源数。
  • 2、如果没有则死锁,如果有则模拟该进程结束,收回资源.资源添加到可用的资源中
  • 3、重复直到所有进程为终止。

看起来这个过程非常简单清晰,那么话不多说直接开干。

首先定义好需要的属性。

int p_num;//进程数
int r_num;//资源数,这里我在初始化时会加一列,作为是否已经终止进程的标志位
int[][] hadtable;//所有进程已经有的资源的记录表
int[][] needtable;//所有进程所需资源的记录表
int[] tousetable;//可用资源
FileWriter fileWriter;//用于写进文件
PrintWriter printWriter;//用于写进文件

表的初始化

这一步略,主要就是传入行列,然后利用scanner输入来初始化三张表。

进行核心的循环判断

public int IfSafe(){
        /***
         * 循环判断:
         * 1、查找needtable 看是否有一行的资源数 均小于等于tousetable中的资源数。
         * 2、如果没有则死锁,如果有则模拟该进程结束,收回资源.资源添加到tousetable中
         * 3、重复直到所有进程为终止。
         * 4、注意将每一步循环输出到同一文件中。
         */
        while(true){
            boolean ifrecyle = false;
            for(int i=0;i<this.p_num;i++){
//                检查是否是未终止的进程
                if(this.hadtable[i][this.r_num-1]!=-1) {
//                    检查是否能满足
                    if (!checkEnough(i,this.needtable[i], this.tousetable)) {
                        continue;
                    }else{
//                        能满足则回收
                        recycleResources(this.hadtable[i]);
                        ifrecyle =true;
                    }
                }
            }
            if(checkAllprocess()){
                return 1;
            }else{
                if(ifrecyle == false){
                    break;
                }
            }
        }
        if(checkAllprocess()){
            return 1;
        }
        return -1;
    }

另外的一些抽象出来的辅助方法如下:

用于判断某一行(某一个进程)是否可以申请资源

/**
 * 用于做循环的第一步判断,判断可用资源是否满足进程需求资源。
 * @param need
 * @param canuse
 * @return true --表示该进程资源可以被满足,false --则为不可以。
 */
private boolean checkEnough(int j,int[] need,int[] canuse){
    saveintoFile(j,need);
    for(int i=0;i<this.r_num-1;i++){

        if(need[i]>canuse[i]){
            printWriter.println("资源不足,无法分配");
            return false;
        }
    }
    printWriter.println("向进程"+j+"分配资源成功");
    return true;
}

在某个资源符合要求后,应该模拟其运行结束并回收资源

/***
 * 回收资源并标记结束
 * @param proc
 */
private void recycleResources(int[] proc){
    for(int i=0;i<proc.length;i++){
        if(i == proc.length-1) {
            proc[i] = -1;//标志为终止
            break;
        }
        this.tousetable[i] += proc[i]; //回收资源
    }
}

用于判断是否所有进程都已经终止

private boolean checkAllprocess(){
        for(int i=0;i<this.p_num;i++){
//            表示仍有进程未终止
            if (this.hadtable[i][this.r_num-1]!=-1){
                return false;
            }
        }
        return true;
    }

抽离出来的作文件处理的函数(不重要,对算法核心不影响)

/**
 * 将记录保存本地文件
 * @param j
 * @param need
 */
private void saveintoFile(int j,int[] need){
    printWriter.println("进程"+j+"请求资源: ");
    //写入文件
    for(int i=0;i<this.r_num;i++){
        if(i == this.r_num -1){
            if(need[i]!=-1){
                printWriter.print("未终止  ");
            }else{
                printWriter.print("终止  ");
            }
        }else {
            printWriter.print(need[i]+" ");
        }
    }
    printWriter.print("目前可用资源: ");
    for(int k = 0;k<this.r_num-1;k++){
        printWriter.print(this.tousetable[k]+" ");
    }
}

通过简单的main函数,验证课本上的例子,结果符合预期,大功告成!