银行家算法之例实验

目录

一、实验目的

二、实验内容

三、实验结果

四、实验分析及总结


一、实验目的

银行家算法是避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。

二、实验内容

1.编写程序模拟资源分配,实现银行家算法及系统安全检查算法。

2.假设系统有5个进程,3类资源,程序能模拟系统情况,初始化各进程的资源分配情况,并查看系统内资源分配情况。程序通过安全检查算法可以检查任意时刻系统的安全状况,如果该时刻系统安全,并给出一个安全序列。每当一个进程申请资源时,程序按银行家算法试探分配,并检查分配后系统的安全状态,如果系统安全则分配资源,否则不分配,返还试探分配的资源。

3.程序代码规范,有可视化的运行界面。

三、实验结果

1.主要代码及解释如下:

package my.algorithm;

import java.util.Scanner;

/**
 * 操作系统实验-银行家算法
 * @author HP
 *
 */
public class BankerAlgorithm {

	private static int[] Avaiable;//系统可利用资源向量数组。其元素值代表每一类资源的个数
	private static int[][] Max;//最大需求矩阵。大小为n*m 其定义了系统中n个进程中,分别对m类资源的最大需求数
	private static int[][] Allocation;//分配矩阵。大小为n*m,其定义了系统中n个进程中,已分配的m类资源数
	private static int[][] Need;//需求矩阵。大小为n*m,其定义了n个进程m类资源的尚缺资源数	
	
	//初始化系统的进程和资源数以及资源分配情况
	public static void initSource() {
		System.out.println("---<银行家算法之例>---"
				+ "\n假设系统中有5个进程P0-P4、和三类资源A、B、C、\nT0时刻,系统的资源分配情况如下:");
		Avaiable=new int[] {3,3,2};
		Max=new int[][] {{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
		Allocation =new int[][] {{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
		Need= new int[][] {{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};	
	}
	//资源分配表
	public static void look() {
		System.out.println("\n资源\tMax\tAllocation\tNeed\tAvailable");
		System.out.println("      A、B、C\t  A、B、C\t       A、B、C\t  A、B、C");
		for(int i=0;i<5;i++) {
			System.out.print("P"+i+"    ");
			for(int j=0;j<3;j++) {
				System.out.print(Max[i][j]+" ");
			}
			System.out.print("\t  ");
			for(int j=0;j<3;j++) {
				System.out.print(Allocation[i][j]+" ");
			}
			System.out.print("       ");
			for(int j=0;j<3;j++) {
				System.out.print(Need[i][j]+" ");
			}
			if(i==0) {
				System.out.print("\t  ");
				for(int j=0;j<3;j++) {
					System.out.print(Avaiable[j]+" ");
				}
			}
			System.out.println();
		}
	}
	//银行家算法
	public static void banker() {
		Scanner sc=new Scanner(System.in);
		int count=0;//标志变量
		int pceNum;//请求进程
		int[] Request=new int[3];//请求向量
		System.out.print("\n请选择请求资源的进程(进程号:0···):");
		pceNum=sc.nextInt();//用户选择进程
		System.out.print("请输入A、B、C类资源的请求个数:");
		for(int i=0;i<3;i++) {
			Request[i]=sc.nextInt();
		}
		for(int j=0;j<3;j++) {
			if(Request[j]<=Need[pceNum][j]) {//判断请求资源是否小于所需资源
				if(Request[j]<=Avaiable[j]) {//判断请求资源是否小于可利用资源
					//试探分配资源给该进程
					Avaiable[j]-=Request[j];
					Allocation[pceNum][j]+=Request[j];
					Need[pceNum][j]-=Request[j];
					count++;
				}else {
					System.out.println("---------------请求资源大于系统可利用资源!");
					break;
				}
			}else {
				System.out.println("---------------请求资源大于所需资源最大值!");
				break;
			}
		}
		if(count==3) {
			if(safe()) {//当试探分配完成后,检查系统是否安全
				System.out.println("\n--------------可分配资源,进程请求资源成功!");
			}else {//系统不安全,则返还试探分配的资源
				for(int j=0;j<3;j++) {
					Avaiable[j]+=Request[j];
					Allocation[pceNum][j]-=Request[j];
					Need[pceNum][j]+=Request[j];		
				}
				System.out.println("-------------请求失败!若分配资源系统将处于不安全状态!");
			}
		}
	}
	//安全性检查算法
	public static boolean safe() {
		//工作资源向量数组。其元素值代表每一类资源可利用的资源的个数。Work=Available
		int[] Work=new int[3];			
		//大小为进程数量,表示系统是否有足够资源分配给进程,如是Finish[i]=true.初始化Finish,先假设所有进程资源都未释放。
		boolean[] Finish=new boolean[] {false,false,false,false,false};
		int seq[]=new int[5];//安全序列数组,存放安全进程序列
		int count0=0;//判断安全进程个数
		for(int i=0;i<3;i++) {//令工作向量值=可利用资源向量值
			Work[i]=Avaiable[i];
		}
		for(int i=0;i<5;i++) {//循环检索,依次找出可满足资源的进程
			//每次检索从5个进程中查找出为满足资源释放的进程
			for(int j=0;j<5;j++) {//j表示进程的序号
				if(Finish[j]==false) {//false未释放资源进程,开始判断
					int count1=0;//用来计数每一类资源是否满足
					for(int k=0;k<3;k++) {//检查是否ABC三类资源都满足,k表示每类资源
						if(Need[j][k]<=Work[k])  count1++;
						}
					if(count1==3) {//如果三类资源都满足
						for(int l=0;l<3;l++) {//l表示每类资源
							//将进程已分配每类资源都释放
							Work[l]+=Allocation[j][l];
						}
						Finish[j]=true;//释放完成,记为true
						seq[i]=j;//将该进程记录到安全序列
						count0++;//
						break;//找到符合进程,记录序列号,跳出循环
					}
				}else {
					continue;//结束本次循环,检索下一进程
				}	
			}	
		}
		if(count0==5) {
			System.out.print("---系统状态安全!\n存在安全序列:");
			for (int i : seq) {
				System.out.print("P"+i+"、");
			}
			return true;
		}else {
			System.out.println("系统状态不安全!分配资源失败!");
			return false;
		}
		
	}
	//主调用函数
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int op;boolean yes=true;//控制菜单选择的变量
		initSource();//初始化系统状态
		look();//查看资源分配表
		System.out.println("\n----操作选择----\n"
				+ "*1.查看资源分配表\n"
				+ "*2.查看系统安全状态\n"
				+ "*3.请求资源\n"
				+ "*4.退出");
		while(yes){
			System.out.print("\n请选择操作:");
			op=scanner.nextInt();
			switch (op) {
			case 1: {look();break;}//查看资源分配表
			case 2: {safe();break;}//系统安全检查
			case 3: {banker();break;}//银行家算法请求资源
			case 4: {yes=false;break;}
			default:
				throw new IllegalArgumentException("Unexpected value: " + op);
			}
		}
		System.out.println("----------结束!");
		scanner.close();			
	}
}

2.实验测试结果如下:

(1)系统模拟初始化各进程的资源分配情况,并显示资源分配情况表,如下图所示:

(2)选择操作2查看当前系统安全状态,若安全,并打印一个安全序列。T0时刻的安全状态如下图所示:

(3)可见当前系统处于安全状态,可进行请求资源分配。继续选择操作3请求资源,输入要需要请求资源的进程及请求的各类资源数。操作及结果如下图所示:

 

(4)当P1请求完后,可利用资源数为:Available(2,2,0),若继续请求资源,当请求资源不合法时,程序提示错误,并不给予资源分配。当进程请求资源数大于自身所需资源数时,实验结果如下图所示:

 

(5)当进程请求资源数大于系统可利用资源数时,进程等待,不分配资源,实验如下图所示:

 

(6)若此时P0请求资源,发出请求Request(0,2,0),请求资源合法,系统假定分配资源,并进行安全性检查,发现若分配资源给P0,系统将处于不安全状态,故返还试探分配的资源,资源分配情况不变。实验操作及结果如下图所示:

 

四、实验分析及总结

1.实验原理分析:

编写该程序需要模拟系统中进程的资源配分情况,实验中假定系统有5个进程和A、B、C三类资源。此外还需要定义用于存储和表示资源和进程关系的变量,实验中定义了表示系统可利用资源向量数组Available[]、最大需求矩Max[][]、已分配资源矩阵Allocation[][]、需求矩阵Need[][]四个全局变量。

在安全性检查算法中,设置两个向量:工作向量Work[],Finish[]。开始安全性检查时,令Work[]=Avaiable[],Finish[]假设全为false,进行循环检查,从进程中找到满足条件的进程,满足其资源,执行后回收分配给该进程的资源,finish[i]=true,继续下一轮检查,若所有进程finish[i]=true,则表示系统状态安全。

在银行家算法中,通过用户输入来表示进程的请求向量Request(a,b,c),并进行请求资源合法性判断,合法则进行试探性分配资源,再通过安全性检查算法来判定系统是否处于安全状态。安全则分配资源,不安全则返还试探分配的资源。

2.实验总结

通过该实验,使我更加深刻理解死锁的概念和如何避免死锁的方法,同时对银行家算法的避免死锁的思想有了深刻的认识和实践经历。

此外实验的同时也巩固了操作系统的理论知识:

(1)银行家算法是一种用来避免操作系统死锁出现的有效算法。

(2)死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

(3)死锁的发生必须具备以下四个必要条件:

·互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

·请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

·不抢占条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

·循环等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

(4)为实现银行家算法,系统必须设置若干数据结构,同时要解释银行家算法,必须先解释操作系统安全状态和不安全状态。安全序列:是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值