预防和避免死锁的方法及银行家算法的java简单实现

  • 预防死锁
    (1) 摒弃“请求和保持”条件
    基本思想:规定所有进程在开始运行之前,要么获得所需的所有资源,要么一个都不分配给它,直到所需资源全部满足才一次性分配给它。
    优点:简单、易于实现且很安全
    缺点:资源被严重浪费,进程延迟运行
    (2) 摒弃“不剥夺”条件
    基本思想:当一个已经保持了某些资源的进程,再提出新的资源请求而不能立即得到满足时,必须释放它已经保持了的所有资源,待以后需要时再重新申请。这意味着某一进程已经占有的资源,在运行过程中会被暂时地释放掉,也可认为是被剥夺了,从而摒弃了“不剥夺”条件。
    (3) 摒弃“环路等待”条件
    基本思想:系统将所有资源按类型进行线性排队,并赋予不同的序号,所有进程对资源的请求必须严格按照资源序号递增的次序提出。由于只允许在保持高顺位资源的情况下申请低顺位资源,不允许在保持低顺位资源的情况下申请高顺位资源,因此环路等待条件被破坏。
  • 避免死锁
    (1) 系统的安全状态
    所谓安全状态,是指系统能按某种进程顺序(P1,P2,…,Pn),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成,称系统处于安全状态, 称〈P1,P2,…,Pn〉序列为安全序列 。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。
    安全状态,一定不会死锁;
    不安全状态不必然死锁;
    避免死锁的实质在于:系统在进行资源分配时,如何避免系统不进入不安全状态。
    (2) 利用银行家算法避免死锁
    一、进程向操作系统请求分配资源相当于用户银行贷款,为保证资金安全:
    ①当一个顾客对资金的最大需求量不超过银行家现有的资金就可以接纳该顾客;
    ②顾客可以分期贷款,但总数不能超过最大需求
    ③银行家现有资金不满足顾客,可以推迟,但顾客会在有限时间内获得贷款
    ④顾客得到全部资金后会在有限时间内归还。
    二、从操作系统角度来看:
    进程首次申请资源,系统现存资源>线程最大资源需求时分配,否则延迟;
    进程执行期间,进程本次申请的资源数<系统剩余资源数,分配,否则延迟.
    三、举个栗子
    假定系统中有五个进程{P0,P1,P2,P3,P4}和三类资源{A,B,C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如下:
    在这里插入图片描述
    存在安全序列:
    (P1,P3,P4,P0,P2) OR (p1 p3 p0 p2 p4)
  • 银行家算法的java简单实现
    ①首先创建一个用户类
/*
 * 用户类
 */
public class Person {
	
	//用户名字
	private String name;
	//用户所需最大资源数
	private int[] max;
	//用户现有资源数
	private int[] allocation;
	//用户所需资源数
	private int[] need;
	//用户请求资源数,本实例中请求数require等于need所需资源数
	private int[] require;
	
	
	public Person(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return name;
	}
	
	public void setMax(int[] max) {
		this.max = max;
		System.out.println(name + "最大资源需求");
		for(int i = 0; i < max.length; i++) {
			System.out.print(i + ":" + max[i] + " ");
		}
		System.out.println();
	}
	
	public int[] getMax() {
		return max;
	}

	public int[] getAllocation() {
		return allocation;
	}

	public void setAllocation(int[] allocation) {
		this.allocation = allocation;
		System.out.println(name + "当前拥有资源");
		for(int i = 0; i < allocation.length; i++) {
			System.out.print(i + ":" + allocation[i] + " ");
		}
		System.out.println();
	}

	public int[] getNeed() {
		return need;
	}

	public void setNeed() {
		int[] need1 = new int[max.length];
		for(int i = 0; i < max.length; i++) {
			need1[i] = max[i] - allocation[i];
		}
		this.need = need1;
		System.out.println(name + "所需资源");
		for(int i = 0; i < need.length; i++) {
			System.out.print(i + ":" + need[i] + " ");
		}
		System.out.println();
	}

	public int[] getRequire() {
		return require;
	}

	public int[] setRequire() {
		this.require = need;
		System.out.println(name + "发起请求");
		for(int i = 0; i < require.length; i++) {
			System.out.print(i + ":" + require[i] + " ");
		}
		System.out.println("");
		System.out.println("----------");
		return require;
	}
	
}

②创建银行家类并进行测试

public class BlankTest {

	//list1中存储竞争资源的用户
	public static ArrayList<Person> list1 = new ArrayList<>();
	//list2已经完成的用户
	public static ArrayList<Person> list2 = new ArrayList<>();
	//银行家现有资源
	public static int[] avaiable = new int[3];
	/*
	 * 是否可以分配,即请求是否小于系统现有资源
	 */
	public static boolean CanRequired(int[] avaiable, int [] require) {
		for(int i = 0; i < avaiable.length; i++) {
			if(avaiable[i] < require[i]) {
				return false;
			}
		}
		return true;
	}
	/*
	 * 分配动作
	 */
	public static void send(int[] avaiable, int [] allocation) {
		
		System.out.println("系统现有资源");
		for(int j = 0; j < avaiable.length; j++) {
			avaiable[j] = avaiable[j] + allocation[j];
			System.out.print(avaiable[j] + " ");
		}
		System.out.println();
	}
	/*
	 * 初始化数据和测试
	 */
	public static void main(String[] args) {
		//初始化资源
		avaiable[0] = 3;
		avaiable[1] = 3;
		avaiable[2] = 2;
		int[] max1 = new int[3];
		max1[0] = 7;
		max1[1] = 5;
		max1[2] = 3;
		int[] allocation1 = new int[3];
		allocation1[0] = 0;
		allocation1[1] = 1;
		allocation1[2] = 0;
		Person p0 = new Person("p0");
		p0.setMax(max1);
		p0.setAllocation(allocation1);
		p0.setNeed();
		int[] max2 = new int[3];
		max2[0] = 3;
		max2[1] = 2;
		max2[2] = 2;
		int[] allocation2 = new int[3];
		allocation2[0] = 2;
		allocation2[1] = 0;
		allocation2[2] = 0;
		Person p1 = new Person("p1");
		p1.setMax(max2);
		p1.setAllocation(allocation2);
		p1.setNeed();
		int[] max3 = new int[3];
		max3[0] = 9;
		max3[1] = 0;
		max3[2] = 2;
		int[] allocation3 = new int[3];
		allocation3[0] = 3;
		allocation3[1] = 0;
		allocation3[2] = 2;
		Person p2 = new Person("p2");
		p2.setMax(max3);
		p2.setAllocation(allocation3);
		p2.setNeed();
		int[] max4 = new int[3];
		max4[0] = 2;
		max4[1] = 2;
		max4[2] = 2;
		int[] allocation4 = new int[3];
		allocation4[0] = 2;
		allocation4[1] = 1;
		allocation4[2] = 1;
		Person p3 = new Person("p3");
		p3.setMax(max4);
		p3.setAllocation(allocation4);
		p3.setNeed();
		int[] max5 = new int[3];
		max5[0] = 4;
		max5[1] = 3;
		max5[2] = 3;
		int[] allocation5 = new int[3];
		allocation5[0] = 0;
		allocation5[1] = 0;
		allocation5[2] = 2;
		Person p4 = new Person("p4");
		p4.setMax(max5);
		p4.setAllocation(allocation5);
		p4.setNeed();
		System.out.println();
		list1.add(p0);
		list1.add(p1);
		list1.add(p2);
		list1.add(p3);
		list1.add(p4);
		//index用于记录每趟循环是否有用户得到资源,没有说明不存在安全序列,结束分配
		int index = 0;
		//开始分配
		for(int x = 0; x < list1.size(); x++) {
			if(index != x) {
				System.out.println("找不到安全队列");
				break;
			}
			for(int z = 0; z < list1.size(); z++) {
				/*
				 * 判断请求资源是否小于系统现有资源,并且该用户需要满足不在安全序列中,这里的请求是简单的一次请求
				 */
				if(CanRequired(avaiable, list1.get(z).setRequire()) && !list2.contains(list1.get(z))) {
					System.out.println("该请求得到响应");
					index++;
					send(avaiable, list1.get(z).getAllocation());
					list2.add(list1.get(z));
					break;
				}

			}
		}
		System.out.println();
		for(Person p: list2) {
			System.out.print(p + " ");
		}
		
	}
}

③测试结果
初始化资源
初始化资源
分配
在这里插入图片描述
最终结果
在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【实验目的】 1. 理解死锁的概念; 2. 用高级语言编写和调试一个银行家算法程序,以加深对死锁的理解。 【实验准备】 1. 产生死锁的原因  竞争资源引起的死锁  进程推进顺序不当引起死锁 2.产生死锁的必要条件  互斥条件  请求和保持条件  不剥夺条件  环路等待条件 3.处理死锁的基本方法预防死锁避免死锁  检测死锁  解除死锁 【实验内容】 1. 实验原理 银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。与预防死锁的几种方法相比较,限制条件少,资源利用程度提高了。缺点:该算法要求客户数保持固定不变,这在多道程序系统中是难以做到的;该算法保证所有客户在有限的时间内得到满足,但实时客户要求快速响应,所以要考虑这个因素;由于要寻找一个安全序列,实际上增加了系统的开销.Banker algorithm 最重要的一点是:保证操作系统的安全状态!这也是操作系统判断是否分配给一个进程资源的标准!那什么是安全状态?举个小例子,进程P 需要申请8个资源(假设都是一样的),已经申请了5个资源,还差3个资源。若这个时候操作系统还剩下2个资源。很显然,这个时候操作系统无论如何都不能再分配资源给进程P了,因为即使全部给了他也不够,还很可能会造成死锁。若这个时候操作系统还有3个资源,无论P这一次申请几个资源,操作系统都可以满足他,因为操作系统可以保证P不死锁,只要他不把剩余的资源分配给别人,进程P就一定能顺利完成任务。 2.实验题目 设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。 3.算法描述 我们引入了两个向量:Resourse(资源总量)、Available(剩余资源量) 以及两个矩阵:Claim(每个进程的最大需求量)、Allocation(已为每个进程分配的数量)。它们共同构成了任一时刻系统对资源的分配状态。 向量模型: R1 R2 R3 矩阵模型: R1 R2 P1 P2 P3 这里,我们设置另外一个矩阵:各个进程尚需资源量(Need),可以看出 Need = Claim – Allocation(每个进程的最大需求量-剩余资源量) 因此,我们可以这样描述银行家算法: 设Request[i]是进程Pi的请求向量。如果Request[i , j]=k,表示Pi需k个Rj类资源。当Pi发出资源请求后,系统按下述步骤进行检查: (1) if (Request[i]<=Need[i]) goto (2); else error(“over request”); (2) if (Request[i]<=Available[i]) goto (3); else wait(); (3) 系统试探性把要求资源分给Pi(类似回溯算法)。并根据分配修改下面数据结构中的值。 剩余资源量:Available[i] = Available[i] – Request[i] ; 已为每个进程分配的数量: Allocation[i] = Allocation[i] + Request[i]; 各个进程尚需资源量:Need[i] = Need[i]-Request[i]; (4) 系统执行安全性检查,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程以完成此次分配;若不安全,试探方案作废,恢复原资源分配表,让进程Pi等待。 系统所执行的安全性检查算法可描述如下: 设置两个向量:Free、Finish 工作向量Free是一个横向量,表示系统可提供给进程继续运行所需要的各类资源数目,它含有的元素个数等于资源数。执行安全算法开始时,Free = Available .标记向量Finish是一个纵向量,表示进程在此次检查中中是否被满足,使之运行完成,开始时对当前未满足的进程做Finish[i] = false;当有足够资源分配给进程(Need[i]<=Free)时,Finish[i]=true,Pi完成,并释放资源。 (1)从进程集中找一个能满足下述条件的进程Pi ① Finish[i] == false(未定) ② Need[i] D->B->A A 1 6 B 1 5 C 2 4 D 4 7 Available = (2) ; Resourse = (10) ; 测试结果如下 process number:5 resource number:4 resource series:6 3 4 2 assined matrix:p0:3 0 1 1 p1:0 1 0 0 p2:1 1 1 0 p3:1 1 0 1 p4:0 0 0 0 needed matrix: p0:1 1 0 0 p1:0 1 1 2 p2:3 1 0 0 p3:0 0 1 0 p4:2 1 1 0 p3-->p4-->p0-->p2-->p1 p3-->p4-->p0-->p1-->p2 p3-->p0-->p4-->p2-->p1 p3-->p0-->p4-->p1-->p2 p3-->p0-->p2-->p4-->p1 p3-->p0-->p2-->p1-->p4 p3-->p0-->p1-->p4-->p2 p3-->p0-->p1-->p2-->p4 it is safe,and it has 8 solutions

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值