银行家算法回顾[JAVA实现]

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> hot3.png

分析了一下银行家算法,基于银行家算法做了一个小程序.

银行家算法主要用于操作系统进程管理程序中,用于防止死锁.

接下来这段代码将模拟这一过程.

首先让我们知道银行家算法在进程资源分配中主要做什么:

    进程管理系统掌控着操作系统的一切资源.几乎每个进程都要向操作系统索要资源.但是系统的资源又有限.试想:

    当操作系统掌握A,B资源,有进程P1,P2,同一时刻,P1和P2都向操作系统索取AB两个资源,而操作系统却把A分给了P1,B分给了P2,这个时候P1和P2只占有一半资源,如果它们不释放,那么这两个进程就会进入死锁状态,在系统中无休止地请求资源.

为了解决这种问题,银行家算法被应用到进程管理系统中,值得注意的是,之所以叫做银行家算法,是因为这个算法最早被应用于银行向客户贷款的案例中,银行需要分析贷款是否安全,即一段时间内满足所有客户.

 

算法主要过程如下:

1.数据结构

    Max矩阵,行号表示进程,列号表示进程所需的最大资源数目.

194625_nGf5_2481244.png

    Allocation矩阵,行号表示进程号,列表示已经分配给进程的资源.

    Need矩阵,表示仍然需要的资源数.Need由Max - Allocation得到.

    Available向量,用于表示当前系统中可分配的资源.初始化为OS所有可分配资源.

195057_N4XT_2481244.png

以上数据结构可用1维和2维数组表示.非常简单.

2.银行家算法

    1.某进程某时刻向操作系统索要资源,用Request(i)表示,如果系统中有3类资源,则Request(1) = {1,2,3}表示进程1向系统所有A:1 B:2 C:3.

    2.如果Request(i)[ j ] <= Need[i, j]则进入第3步.(i表示进程号,j是资源类,按照3类资源,这里的j该是0,1,2 ),否则报错.

    3.同样,如果Request < Available,跳向4,否则报错.

    4.系统尝试将资源分配给P(i),然后修改数据结构的值:

            Available -= Request ( 向量的减法应该会吧? 就是每个元数据相减.)

            Allocation += Request

            Need -= Request

    5.执行安全检查,若可得出安全序列,则分配给进程资源.若得不出,说明分配资源给该进程是不安全的行为,可能导致死锁,让该进程的请求挂起,稍后再尝试.

 

    安全检查步骤:

        1.将Available复制一份儿,命名Work.,为所有进程设置一个Finish向量,默认初始化为false.

        2.从进程中找出一个进程,Finish为false,Need <= Work.若找到执行3,否则4.

        3.当进程获取到资源,执行完毕,然后将它持有的所有资源都会释放掉.

                Work = Work + Allocation

                Finish = true

                跳转到第二步

        4.如果所有Finish的元数据都为true,说明所有进程都能执行完毕,则表示系统处于安全状态.否则,不安全.

(安全序列在安全检查过程中得出.即一个能够执行完所有进程的进程号顺序.这个序列是不唯一的,找到一个即可.)

3.算法实现代码

    1.数据结构

        

    //max,need,allocation use matrix to express.
	private static int[][] Max;
	private static int[][] Allocation;
	private static int[][] Need;
	
	//about safety.
	private static int[] Work;
	private static boolean[] Finish;
	private static int[] safeSequence;
	private static int seqCounter = 0;
	
	//the resources can be allocated that os handled
	private static int[] Available;
	
	private static int processCount = 0;
	private static int resourceCount = 0;
	
	private static int[] Request;

    2.实现模拟分配资源:

//when OS ready,allocate resource to process
	private static boolean allocateRequest(int process){
		if(process < 0)	return false;
 		//1,2.judge Request amount whether is illegal
		for(int j = 0; j < resourceCount; j++){
			if(Request[j] > Need[process][j]){
				System.out.println("Request amount is over your Need");
				return false;
			}
			if(Request[j] > Available[j]){
				System.out.println("Request amount is over the amount that OS handled");
				return false;
			}
		}
		//3.allocate the resource to process.
		for(int j = 0; j < resourceCount; j++){
			Available[j] -= Request[j];
			Allocation[process][j] += Request[j];
			Need[process][j] -= Request[j];
		}
		return true;
	}

    3.实现安全分析:

//banker algorithm to check whther safe.
	//if safe,return a serial key.else return null;
	private static int[] checkSafety(){
		//init safeSequence
		safeSequence = new int[processCount];
		seqCounter = 0;
		//1.copy Available to Work.init Finish to false
		Work = Available.clone();
		Finish = new boolean[processCount];
		
		int process;	//no process choosed.
		while(true){
			process = -1;
			//2.find a process like this finish = false, need < work.
			for(int i = 0; i < processCount; i++){
				if(Finish[i] == false){
					//compare need[i,j] <work[j].i-process number, j-resource number.
					for(int j = 0; j < resourceCount; j++){
						if(Need[i][j] > Work[j]){
							process = -1;
							break;
						}
						process = i;
					}
					if(process != -1){
						safeSequence[seqCounter++] = i;
						break;
					}
				}else{
					process = -1;
				}
			}
			if(process != -1){
				//3.if found,work = work + allocatation , finish = true. to step 2.
				//P[process] exe. and realise the resource,after.
				for(int j = 0; j < resourceCount; j++){
					Work[j] += Allocation[process][j];
				}
				
				Finish[process] = true;
			}else{
				//4.if finish all is true.safe! else unsafe.
				for(int i = 0; i < processCount; i++){
					if(Finish[i] == false)
						return null;
				}
				return safeSequence;
			}
		}
	}
案例分析:

就图中的表我们使用以上算法代码进行分析:

201539_1IYY_2481244.png

表中数据:5个进程

Max矩阵为

201641_Nj2H_2481244.png

其它请参照模糊的表.

分析过程(代码最后放出.):

1.首先我们输入有多少个进程和多少种资源,这里输入5,3:

201903_3LJD_2481244.png

2.初始化的Available,即系统还未分配的资源和已经分配的资源的总和(这里由表相加可知为 10 5 7):

202106_ByzC_2481244.png3

3.接着输入Max矩阵:

202226_EqSp_2481244.png

4.接着输入Allocation矩阵:

202339_zB5C_2481244.png

5.程序自行计算出Need矩阵.和新的Availble资源:

202317_T9kG_2481244.png

6.测试当前状态的安全性:

202521_Aj8T_2481244.png

7.模拟请求,假设现在0号进程需要请求资源以完成任务,请求的资源数为系统总资源数:

202652_4kek_2481244.png

程序尝试分配给进程0资源,但是分配给进程后,发现当前的进程都无法顺利执行完毕,因此最后撤销了分配.

8.我们尝试重新分配,假设1号进程齐宁求{1,2,2}:

202921_1VdL_2481244.png

分配成功,分配成功后系统资源数目已发生变化,不会再revoke.

 

下面贴出整个冗余到不能再冗余的代码:

/*
*use java to realise banker algorithm. 
*@author mrruan(RuanKun) qkmc@outlook.com
*/

import java.util.Scanner;
import java.lang.Math;

class Banker{
	
	//max,need,allocation use matrix to express.
	private static int[][] Max;
	private static int[][] Allocation;
	private static int[][] Need;
	
	//about safety.
	private static int[] Work;
	private static boolean[] Finish;
	private static int[] safeSequence;
	private static int seqCounter = 0;
	
	//the resources can be allocated that os handled
	private static int[] Available;
	
	private static int processCount = 0;
	private static int resourceCount = 0;
	
	private static int[] Request;
	public static void main(String[] args){
		
		Scanner scn = new Scanner(System.in);
		
		System.out.println("Welcome To Bank Algorithm Program");
		System.out.println("note:this is a algorithm to test safety about multi process");
		//1.user input the process num and resource num.

		System.out.println("please input how many processes will be handled:");
		//no any process to deal with exceptions.
		processCount = scn.nextInt();
		System.out.println("please input how many kind of resources will be handled:");
		resourceCount = scn.nextInt();
		//init martrix
		initMatrix(processCount, resourceCount);
		
		//2.input the amount of resources that OS has.
		System.out.println("please input every amount of the " + resourceCount + " resources(" + resourceCount + " integers,space to seperate)");
		for(int i = 0; i < resourceCount; i++){
			//init os resources
			if(scn.hasNextInt())
				Available[i] = scn.nextInt();//didn't check the safety,may cause exceptions.
		}
		System.out.println("now you have the resources and amount:");
		for(int i = 0; i < resourceCount; i++){
			System.out.print((char)(i+65)+ "."+Available[i]+"    ");
		}
		//3.input Max matrix
		System.out.println("\n this step you must input the max resources that every process can handle!");
		for(int i = 0; i < processCount; i++){
			System.out.println("input P" + i + " 's max handle resources("+resourceCount+" integers,space to seperate):");
			System.out.print("P" + i + ": ");
			for(int j = 0; j < resourceCount; j++){
				Max[i][j] = scn.nextInt();
			}
		}
		//we should judge if the max needed is out of the resources that os has.
		for(int i = 0; i < processCount; i++){
			for(int j = 0; j < resourceCount; j++){
				try{
					if(Max[i][j] > Available[j]){
						//error, process cannot go on because the os cannot afford the resources that the process need.
						throw new Exception("OS cannot afford the resources that the process needed.the error process is : P" + i);
					}
				}catch(Exception e){
						e.printStackTrace();
						return;
					}
				
			}
		}
		//print the max matrix.
		System.out.println("this is the max matrix:");
		for(int i = 0; i < processCount; i++){
			for(int j = 0; j < resourceCount; j++)
				System.out.print(Max[i][j] + " ");
			System.out.println();
		}
		
		//4.now set the resources that processes had handled.
		System.out.println("this step is to allocate the resources to every process.");
		for(int i = 0; i < processCount; i++){
			System.out.println("please input th process P" + i + "'s resources," + resourceCount + " integers,space to seperate:");
			for(int j = 0; j < resourceCount; j++){
				Allocation[i][j] = scn.nextInt();		// had not check the exceptions.
			}
		}
		//now check the Allocation whether is legal.
		for(int i = 0; i < processCount; i++){
			for(int j = 0; j < resourceCount; j++){
				try{
					if(Allocation[i][j] > Available[j]){
						System.out.println(Allocation[i][j] + "  " + Available[j]);
						throw new Exception("Allocated an illegal amount of resource,the error process is P" + i);
					}
					if(Allocation[i][j] > Max[i][j])
						throw new Exception("you allocated is out of Max.position is : P " + i + " the kind is :" + (char)(j+65));
				}catch(Exception e){
					e.printStackTrace();
					return;
				}
			}
		}
		//check sum.
		int tmp = 0;	//this is for the follow checking.
		for(int i = 0; i < resourceCount; i++){
			for(int j = 0; j < processCount; j++){
				tmp += Allocation[j][i];
			}
			try{
				if(tmp > Available[i]){
					throw new Exception("over resource,position is : " + (char)(i + 65));
				}
			}catch(Exception e){
				e.printStackTrace();
				return;
			}
			tmp = 0;
				
		}
		vectorMinusMatrix(Available,Allocation, processCount, resourceCount);
		//print the allocated matrix.
		System.out.println("this is the Allocation matrix:");
		for(int i = 0; i < processCount; i++){
			for(int j = 0; j < resourceCount; j++)
				System.out.print(Allocation[i][j] + " ");
			System.out.println();
		}
		System.out.println("this is the Available resources after allocatation:");
		for(int j = 0; j < resourceCount; j++)
			System.out.print(Available[j] + " ");
		System.out.println();
			
		//5.get still need matrix
		Need = matrixMinusMatrix(Max, Allocation, processCount, resourceCount);
		System.out.println("this is the Need matrix:");
		for(int i = 0; i < processCount; i++){
			for(int j = 0; j < resourceCount; j++)
				System.out.print(Need[i][j] + " ");
			System.out.println();
		}
		System.out.println("the multi process module has been set up.");
		System.out.println("please select a option");
		int sw;
		while(true){
			System.out.println("\n 1. check the state whether safe.");
			System.out.println("2. try to allocate resources to process.");
			sw = scn.nextInt();
			switch(sw){
				case 1:
				if (checkSafety() != null){
					System.out.println("it's safe. the safeSequence is ");
					for(int i = 0; i < seqCounter; i++)
						System.out.print(safeSequence[i] + "  ");
				}else{
					System.out.println("it's unsafe.");
				}
				break;
				case 2:
				int process = -1;
				Request = new int[resourceCount];
				System.out.println("please input the process Number:");
				process = scn.nextInt();
				System.out.println("please input the requested amount of resource.(it's "+ resourceCount +" integers):");
				for(int i = 0; i < resourceCount; i++){
					Request[i] = scn.nextInt();
				}
				//then try to allocate the requested resource to process.
				if(allocateRequest(process))
					//check
					if (checkSafety() != null){
						System.out.println("after allocated,it's safe. the safeSequence is ");
						for(int i = 0; i < seqCounter; i++)
							System.out.print(safeSequence[i] + "  ");
						System.out.println();
					}else{
						System.out.println("after allocated,it's unsafe.");
						//if unsafe,DO NOT allocate
						if(revokeRequest(process)){
							System.out.println("Revoked allocation");
						}
					}
					
				break;
			}
		}
		//6.should get a safe serial key.
	}
	
	
	/*
	* other methods
	*
	*/
	
	//create matrix and init.
	private static void initMatrix(int processCount,int resourceCount){
		Max = new int[processCount][resourceCount];
		Allocation = new int[processCount][resourceCount];
		Need = new int[processCount][resourceCount];
		Available = new int[resourceCount];
	}
	
	//vector - matrix.
	private static void vectorMinusMatrix(int[] vector, int[][] matrix, int row, int col){
		int sum = 0;
		//System.out.println("print martrix");
		//for(int i = 0; i < row; i++)
		//	for(int j = 0; j < col; j++)
		//		System.out.print(matrix[i][j] + "  ");
		for(int i = 0; i < col; i++){
			for(int j = 0; j < row; j++){
				sum += matrix[j][i];
			}
			//System.out.println("------------------------------------\n"+"the sum is " + sum +"\n------------------------------------");
			vector[i] -= sum;
			sum = 0;
		}
	}
	
	//two matrix minus.
	private static int[][] matrixMinusMatrix(int[][] matrix1, int[][] matrix2, int row, int col){
		int[][] rs = new int[row][col];
		
		for(int i = 0; i < row; i++){
			for(int j = 0; j < col; j++){
				rs[i][j] = Math.abs(matrix1[i][j] - matrix2[i][j]);
			}
		}
		return rs;
	}
	
	//judge whether a vector is bigger than another.
	//if vector1 > vector2, that means vector1's every elem is bigger than vector2
	private static boolean compareVector(int[] vector1, int[] vector2,int length){
		for(int i = 0; i < length; i++){
			if(vector1[i] < vector2[i])
				return false;
		}	
		return true;
	}
	
	//banker algorithm to check whther safe.
	//if safe,return a serial key.else return null;
	private static int[] checkSafety(){
		//init safeSequence
		safeSequence = new int[processCount];
		seqCounter = 0;
		//1.copy Available to Work.init Finish to false
		Work = Available.clone();
		Finish = new boolean[processCount];
		
		int process;	//no process choosed.
		while(true){
			process = -1;
			//2.find a process like this finish = false, need < work.
			for(int i = 0; i < processCount; i++){
				if(Finish[i] == false){
					//compare need[i,j] <work[j].i-process number, j-resource number.
					for(int j = 0; j < resourceCount; j++){
						if(Need[i][j] > Work[j]){
							process = -1;
							break;
						}
						process = i;
					}
					if(process != -1){
						safeSequence[seqCounter++] = i;
						break;
					}
				}else{
					process = -1;
				}
			}
			if(process != -1){
				//3.if found,work = work + allocatation , finish = true. to step 2.
				//P[process] exe. and realise the resource,after.
				for(int j = 0; j < resourceCount; j++){
					Work[j] += Allocation[process][j];
				}
				
				Finish[process] = true;
			}else{
				//4.if finish all is true.safe! else unsafe.
				for(int i = 0; i < processCount; i++){
					if(Finish[i] == false)
						return null;
				}
				return safeSequence;
			}
		}
	}
	
	//when OS ready,allocate resource to process
	private static boolean allocateRequest(int process){
		if(process < 0)	return false;
 		//1,2.judge Request amount whether is illegal
		for(int j = 0; j < resourceCount; j++){
			if(Request[j] > Need[process][j]){
				System.out.println("Request amount is over your Need");
				return false;
			}
			if(Request[j] > Available[j]){
				System.out.println("Request amount is over the amount that OS handled");
				return false;
			}
		}
		//3.allocate the resource to process.
		for(int j = 0; j < resourceCount; j++){
			Available[j] -= Request[j];
			Allocation[process][j] += Request[j];
			Need[process][j] -= Request[j];
		}
		return true;
	}
	
	//warning:this method should be invoked after allocatation.
	//or will happen uncaught error.
	private static boolean revokeRequest(int process){
		if(process < 0)	return false;
		for(int j = 0; j < resourceCount; j++){
			Available[j] += Request[j];
			Allocation[process][j] -= Request[j];
			Need[process][j] += Request[j];
		}
		return true;
	}
}



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值