最近正在上操作系统的课程,有道课后作业题如下
编写银行家算法的模拟程序。该程序应该能够循环检查每个提出请求的银行客户,并且能判断出这一请求是否安全。请把有关请求和相应决定的列表输出到一个文件中。
首先翻看课本,找到银行家算法的基本步骤
- 循环判断:
- 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函数,验证课本上的例子,结果符合预期,大功告成!