死锁与银行家算法

目录

死锁的概念

阐述死锁的概念、产生的原因及产生死锁的必要条件;

解决死锁的常见办法或措施;

预防死锁

避免死锁:银行家算法

完整代码

实验运行结果及分析


  • 死锁的概念

  • 阐述死锁的概念、产生的原因及产生死锁的必要条件;

  • 解决死锁的常见办法或措施;

  • 预防死锁

以哲学家就餐问题,分析和阐述预防哲学家就餐时发生死锁几种实现方法;

哲学家问题

主要是互斥问题,假设有5个哲学家,只有同时持有两个筷子(临界资源)才能吃饭(运行)

如果每个哲学家都拿起筷子,那么每个哲学家只有一个筷子,出现死锁现象。

防止死锁方法

1.增加限制:允许最多四个哲学家同时进餐。

2.要求奇数位的哲学家先拿左边的筷子,然后再拿右边的筷子,而偶数哲学家正好相反。

3.仅当一个哲学家左右两支筷子都可用时才允许他抓起来筷子。

(伪代码)

semaphore chopstick[5]={1,1,1,1,1}  
semaphore mutex=1;  
pi(){  
      while(1){  
           p(mutex);  
           p(chopstick[i]);  
           p(chopstick[i+1]%5);  
           v(mutex);  
           吃饭  
           v(chopstick[i]);  
           v(chopstick[i+1]%5);  
           思考  
      }  
}  

当p1运行到p(mutex);时,其他进程不能运行,只有p1得到两个资源,运行v(mutex);其他进程才能运行。这样实现了多个进程互斥的访问两个资源。

  • 避免死锁:银行家算法

核心思想:在进程提出资源申请时,先预判此次分配是否导致系统进入不安全状态,如果导致不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。

下面是流程图

安全状态(存在安全序列):指的是资源请求得到分配后,能找到一条通路,完成其他进程的需求,不至于其他进程得不到资源,造成死锁。

实验所用到数据以及定义代码,如下所示

    static int[][] max;	//最大需求
	static int[][] allocation;//已分配
	static int[][] need; //还需要
	static int[] request;//请求
	static int[] ava;//剩余资源

 按上面流程图,具体实现的代码。

for(int j=0;j<3;j++)
		if(request[j]>need[i][j]) {//判断请求是否合理错误
			System.out.println("出错");
			return;
		}
		for(int j=0;j<3;j++)//判断剩余资源是否满足要求
		if(ava[j]<request[j]) {
			System.out.println("进程:"+i+"等待");
			return;
		}
		if(request[0]==need[i][0]&&request[1]==need[i][1]&&request[2]==need[i][2])boo=true;
		for(int j=0;j<3;j++) {//资源分配
			ava[j]-=request[j];
			need[i][j]-=request[j];
			allocation[i][j]+=request[j];
		}
		int a=0;
		if(boo==true) {
			for(int j=0;j<3;j++) {
				ava[j]+=allocation[i][j];
			}
			System.out.print("进程:"+i+"->");
			a++;
		}
			djks(a);//判断资源分配完后是否处于安全序列

其中djks()函数使用迭代的思想。每一次循环都遍历所有的进程。满足条件的进入迭代,直到所有迭代都结束。

public static void djks(int a) {
		int k=0;
		for(k=0;k<5;k++) {
			if(ava[0]<need[k][0]||ava[1]<need[k][1]||ava[2]<need[k][2]) {
				continue;
			}else if(need[k][0]==0&&need[k][1]==0&&need[k][2]==0) {
					}else{
				for(int j=0;j<3;j++) {
					ava[j]+=allocation[k][j];
					need[k][j]=0;
				}
				System.out.print("\t进程:"+k+"->");
				a++;
				 djks(a);
			}
		}
		if(a==5) {
			System.out.println("安全序列");
		}
	}
  • 完整代码

package bank;  
  
import java.util.Scanner;  
  
public class Text {  
    static int[][] max; //最大需求  
    static int[][] allocation;//已分配  
    static int[][] need; //还需要  
    static int[] request;//请求  
    static int[] ava;//剩余资源  
      
    public static void main(String[] args) {  
        boolean boo=false;  
        Scanner scan=new Scanner(System.in);  
        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}};  
        System.out.println("进程:");  
        int i=scan.nextInt();  
        System.out.println("输入需求:");  
        request=new int[] {scan.nextInt(),scan.nextInt(),scan.nextInt()};  
        ava=new int[] {3,3,2};  
        for(int j=0;j<3;j++)  
        if(request[j]>need[i][j]) {//判断请求是否合理错误  
            System.out.println("出错");  
            return;  
        }  
        for(int j=0;j<3;j++)//判断剩余资源是否满足要求  
        if(ava[j]<request[j]) {  
            System.out.println("进程:"+i+"等待");  
            return;  
        }  
        if(request[0]==need[i][0]&&request[1]==need[i][1]&&request[2]==need[i][2])boo=true;  
        for(int j=0;j<3;j++) {//资源分配  
            ava[j]-=request[j];  
            need[i][j]-=request[j];  
            allocation[i][j]+=request[j];  
        }  
        int a=0;  
        if(boo==true) {  
            for(int j=0;j<3;j++) {  
                ava[j]+=allocation[i][j];  
            }  
            System.out.print("进程:"+i+"->");  
            a++;  
        }  
            djks(a);//判断资源分配完后是否处于安全序列  
          
    }  
    //使用迭代实现  
    public static void djks(int a) {  
        int k=0;  
        for(k=0;k<5;k++) {  
            if(ava[0]<need[k][0]||ava[1]<need[k][1]||ava[2]<need[k][2]) {  
                continue;  
            }else if(need[k][0]==0&&need[k][1]==0&&need[k][2]==0) {  
                    }else{  
                for(int j=0;j<3;j++) {  
                    ava[j]+=allocation[k][j];  
                    need[k][j]=0;  
                }  
                System.out.print("\t进程:"+k+"->");  
                a++;  
                 djks(a);  
            }  
        }  
        if(a==5) {  
            System.out.println("安全序列");  
        }  
    }  
}  
  • 实验运行结果及分析

五个进程都得到满足,所以存在安全序列

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值