银行家算法

死锁预防之银行家算法 Dijkstra提出了一种能够避免死锁的调度算法,称为银行家算法。它的模型基于一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,每个客户都有一个贷款额度,银行家知道不可能所有客户同时都需要最大贷款额,所以他只保留一定单位的资金来为客户服务,而不是满足所有客户贷款需求的最大单位。这里将客户比作进程,贷款比作设备,银行家比作系统。客户们各自做自己的生意,在某些时刻需要贷款。在某一时刻,客户已获得的贷款和可用的最大数额贷款称为与资源分配相关的系统状态。 阅读详情

安全序列原理

银行家算法
需要分配的资源(MAX)
已经分配的资源(Allocation)
还需要分配的资源(Need)
可分配的资源(Available)
线程(T)

只有当全部线程都满足分配,才是安全序列;
如图:可分配的资源(2,3,3)
T4还需资源(2,2,1),(2,2,1)<(2,3,3)进行分配,T4满足后,可分配资源=T4已经分配的资源+上一次可分配的资源=(2,0,4)+(2,3,3)=(4,3,7);

同理,T5还需资源(1,1,0),进行分配,可分配资源=T5已经分配的资源+上一次可分配的资源=(3,1,4)+(4,3,7)=(7,4,11);

T1还需资源(3,4,7),进行分配,可分配资源=T1已经分配的资源+上一次可分配的资源=(2,1,2)+(7,4,11)=(9,5,13);

T2还需资源(1,3,3),进行分配,可分配资源=T2已经分配的资源+上一次可分配的资源=(4,0,2)+(9,5,13)=(13,5,15);

T3还需资源(0,0,6),进行分配,可分配资源=T5已经分配的资源+上一次可分配的资源=(4,0,5)+(13,5,15)=(17,5,20);

所以安全序列为T4 T5 T1 T2 T3 ;
安全序列不唯一

代码实现


import java.util.Scanner;

public class BankerAlgorithm {
    //定义资源
    //可用资源Availiable 一维数组
    private static int[] availiable = new int[]{3,3,2};
    //最大需求量(每个线程最大资源数)
    private static int[][] max = new int[][]{{7,5,3}, {3,2,2}, {9,0,2}, {2,2,2}, {4,3,3}};
    //已分配的资源(每个线程已分配的)
    private static int[][] allocation = new int[][]{{0,1,0}, {2,0,0},{3,0,2},{2,1,1},{0,0,2}};
    //每个线程还需要的资源数
    private static int[][] need = new int[][]{{7,4,3}, {1,2,2}, {6,0,0}, {0,1,1},{4,3,1}};

    private static void showData(){
        System.out.println("线程号    Max      Allocation      Need");
        System.out.println("       A  B  C     A   B   C    A  B  C");
        for(int i=0; i<5; i++){
            System.out.print(i+"      ");
            for(int j=0; j<3; j++){
                System.out.print(max[i][j]+"  ");
            }
            System.out.print("   ");
            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]+"  ");
            }
            System.out.println();
        }
    }
    //分配数据  给定线程,给定该线程需要的资源数
    public static boolean allocateData(int threadNum, int[] request){
        //比较需要的资源数与可用资源的大小关系,大于则直接返回,不予分配
        if(!(request[0] <= need[threadNum][0] && request[1] <= need[threadNum][1] && request[2] <= need[threadNum][2])){
            System.out.println("请求的资源超过了所需要的资源数,分配错误");
            return false;
        }
        if(!(request[0] <= availiable[0] && request[1] <= availiable[1] && request[2] <= availiable[2])){
            System.out.println("尚无足够资源分配,必须等待");
            return false;
        }
        //尝试分配资源给请求的线程
        for(int i=0; i<3; i++) {
            //可分配资源-请求资源数量
            availiable[i] = availiable[i] - request[i];
            //已分配资源+请求资源数量
            allocation[threadNum][i] = allocation[threadNum][i] + request[i];
            //还需要资源-请求资源数量
            need[threadNum][i] = need[threadNum][i] - request[i];
            //安全性检查 调用安全性算法 查询剩余资源能否满足剩下的线程执行
        }
        boolean flag = checkSafe();
        if(flag == true){
            System.out.println("能够安全分配");
            return true;
        }else{
            System.out.println("不能够安全分配");
            //恢复预分配的数据
            for(int j=0; j<3; j++){
                availiable[j] = availiable[j]+request[j];
                allocation[threadNum][j] = allocation[threadNum][j]-request[j];
                need[threadNum][j] = need[threadNum][j]+request[j];
            }
            return false;
        }
    }

    //安全性检查
    public static boolean checkSafe(){
        //找一个能够满足的线程,完成执行后去执行下一个线程
        int i = 0;//线程号
        boolean finish[] = new boolean[5]; //表示每个线程是否执行成功的标识
        while(i<5){
            //线程执行成功之后拿到一个属于自己的标识
            if(finish[i] == false && need[i][0] <= availiable[0] && need[i][1] <= availiable[1] && need[i][2] <= availiable[2]){
                System.out.println("可以分配,执行成功的线程为"+i);
                finish[i] = true;
                //分配资源之后当前线程执行成功,释放自己之前拥有的资源
                for(int j=0; j<3; j++){
                    availiable[j] = availiable[j] + allocation[i][j];
                }
                //当前线程执行完,从头开始找一个新的可分配资源能够满足的线程
                i = 0;
            } else{
                i++;
            }
        }
        //判断每个线程的标识,如果标识都是执行成功的标识,则返回true
        for(i=0; i<5; i++){
            if(finish[i] == false){
                //反之返回false
                return false;
            }
        }
        return true;
    }


    public static void main(String[] args) {
        showData();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要请求的线程号:");
        int threadNum = scanner.nextInt();
        int request[] = new int[3];
        String[] sources = new String[]{"A", "B", "C"};
        System.out.println("请输入要请求的资源数目:");
        for(int i=0; i<3; i++){
            System.out.println("请输入"+sources[i]+"类资源的数目: ");
            request[i] = scanner.nextInt();
        }
        //请求资源
        allocateData(threadNum, request);


    }
}
[C#]银行家算法的实现 简略介绍了死锁\安全状态; 并给出了使用银行家算法的窗体程序的C#代码. 阅读详情

相关推荐

【避免进程死锁】银行家算法

一、概述 银行家算法(Banker’s Algorithm)是一个避免进程死锁的著名算法,由 Dijkstra 于 1965 年提出。本文为笔者的读书笔记,结构如下: 死锁 银行家算法 例子展示 补充:鸵鸟算法和实际系统中对死锁的处理方式 二、死锁 既然银行家算法就是为了解决进程死锁而出现的,那么首先我们应该先来了解下什么是死锁,以及死锁产生的4个条件。 2.1 什么是死锁 如果一组进程中的每...

Marck的博客 4556

2.3.8银行家算法

全知识整理目录 操作系统整理的目录,包括了整理的所有操作系统的知识。 目录 概述 思想 示例 总结 概述 银行家算法是什么? 银行家算法主要是为了避免死锁的,是针对避免死锁产生的一种算法。 最初是一个人为银行系统设计的,确保银行始终有现金贷款给客户,不会发生不能满足客户的情况。所以叫银行家算法。 那么死锁和前面了解的饥饿有什么关系呢? 死锁和饥饿都是,管理者的问题,即操作系统的问题。 思想 在进程提出资源申请的时候,先预先判断,这次分配是否会导致系统进入不安全状态,...

ybbgrain的历程 1767

操作系统实验银行家算法

银行家算法=-- - 1. 安全状态: 在某时刻系统中所有进程可以排列一个安全序列:{P1,P2,`````Pn},刚称此时,系统是安全的. 所谓安全序列{P1,P2,`````Pn}是指对于P2,都有它所需要剩余资源数量不大于系统掌握的剩余的空间资源与所有Pi(j<i)所占的资源之和. 2.不安全状态可能产生死锁. 目前状态 最大需求 尚需 P1 3 9 6 P2 5 10 5 P3 2 4 2 在每一次进程中申请的资源,判定一下,若实际分配的话,之后系统是否安全. 3.银行家算法的思路: 1),进程一开始向系统提出最大需求量. 2),进程每次提出新的需求(分期贷款)都统计是否超出它事先提出的最大需求量. 3),若正常,则判断该进程所需剩余剩余量(包括本次申请)是否超出系统所掌握的 剩余资源量,若不超出,则分配,否则等待. 4.银行家算法的数据结构. 1),系统剩余资源量A[n],其中A[n]表示第I类资源剩余量. 2),各进程最大需求量,B[m][n],其中B[j][i]表示进程j对i 类资源最大需求. 3),已分配资源量C[m][n],其中C[j][i]表示系统j程已得到的第i资源的数量. 4),剩余需求量.D[m][n],其中D[j][i]对第i资源尚需的数目. 5.银行家算法流程:当某时刻,某进程时,提出新的资源申请,系统作以下操作: 1),判定E[n]是否大于D[j][n],若大于,表示出错. 2),判定E[n]是否大于系统剩余量A[n],若大于,则该进程等待. 3),若以上两步没有问题,尝试分配,即各变量作调整. 4),按照安全性推测算法,判断,分配过后,系统是否安全,若安全,则实际分配,否则,撤消分配,让进程等待. 6."安全性检测"算法 1),先定义两个变量,用来表示推算过程的数据. F[n]=A[n],表示推算过程中,系统中剩余资源量的变化. J[n]=False表示推算过程中各进程是否假设"已完成" 2),流程: 在"剩余"的进程中(在推算)过程中,一些进程假设已完成,查找D[j][n]<=F[n]的进程,找到后令J[j]=True (假设该进程完成),F[n]+D[j][n](该进程所占资源释放),如此循环执行. 若最后,所有的F[n]=True(在推算过程中,所有进程均可以完成),则表示(分配过后)系统是安全的,否则系统是不安全的.

银行家算法—简单易懂解题思路

来个题: 首先明确:Max—最大资源需求量 Need—需要资源量 Allocation—已分配资源量 Available—系统剩余资源数量 其中,Need=Max-Allocation 我们由此可以得出需求量Need的表格 比较Available中的每一个数(2 3 3)是否比Need中的大,很明显p1-5中只有p4和p5满足, (这里说明一下安全序列不是唯一的,即答案不唯一) 如果满足,将Available与Available相加,例如: 此题中将p4中的已分配资源量与系统剩余资源量相加,得到4 3

red_delia的博客 6182

基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理

基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理

watch361的博客 1万+

手把手教你用DCA1000和mmWave Studio 2.0采集AWR1843雷达数据(附驱动安装与常见报错排查)

本文详细介绍了使用DCA1000和mmWave Studio 2.0采集AWR1843毫米波雷达数据的全流程指南,包括硬件连接、驱动安装、软件配置及常见报错排查。通过实战经验分享,帮助开发者快速掌握数据采集技巧,优化雷达参数配置,提升数据质量与采集效率。

weixin_30070339的博客 332

操作系统--课堂问答笔记14--习题答案

课堂笔记学习视频来自 操作系统 说明:其他”课堂问答笔记“也在”操作系统“专栏 【4-1】 这节课课后讨论汇总: 什么是安全状态?安全序列?为什么说存在安全序列,系统不会发生死锁?若存在安全序列,那么安全序列是唯一的吗? 答:若当前状态存在一个安全序列则当前状态是安全状态;安全序列表示按这个序列依次给进程分配资源,系统不会发生死锁;因为安全系列是按每个进程需求各种资源的最大值给进程分配资源...

三桥君 | 人工智能领域专家 1163

拉曼光谱仪的原理与应用——TFN 7G F660手持式拉曼光谱识别仪

拉曼光谱仪的原理与应用——TFN 7G F660手持式拉曼光谱识别仪

TFN_yzgd的博客 928

Linux实现银行家算法

1 实验目的 熟练Linux系统编程操作 了解死锁避免的原理。 研究银行家算法的实现方法。 2 实验任务 最有代表性的避绝死锁的算法是迪杰斯特拉(Dijkstra)提出的银行家算法。该名字的由来是,该算法原本为银行系统而设计,以确保银行在发放现金货款时不会发生不能满足所有客户需要的情况。在 操作系统(OS) 中也可用它来避免死锁。 为实现银行家算法,每个新进程在进人系统时,其都必须申明在运行过程中可能需要每种资源类型的最大单元数目,该数目不应超过系统所拥有的资源总数。当进程清求一组资源时,系统须首先确定

BrilliantAntonio的博客 8751

别再为多相机标定头疼了!用VisionMaster统一坐标系的保姆级教程

本文详细介绍了使用VisionMaster平台解决多相机视觉系统中坐标系统一问题的完整流程。从标定板选择到N点标定,再到实战演练,提供了从原理到落地的全方位指导,帮助工程师高效解决多相机定位引导中的坐标偏差问题。

weixin_38168322的博客 634

Linux ARM平台开发系列讲解(调试篇) 1.6.4 NVIDIA AGX Xavier以太网MAC TO MAC模式

内核发展了那么多年,早已经将这种场景集成到了内核里,具体添加方式如下,本次针对。具体详细描述,可参考本专栏的网络篇和交换机篇,这里就简单的提一句,想要使用。速率和双工状态固定死,使其和交换机的模式一模一样,双方就可以建立通信了。2. MAC TO MAC原理。3. 开启无PHY模式进入内核。模式,本章节记录调试过程。模式,简单来说就是字面意思,以太网部分需要与交换机。,其他芯片也是一样的。修改设备树文件,将与。

DSMGUOGUO的博客 1530

银行家算法(C++实现)

操作系统实验内容,银行家算法的实现,基于C++语言

m0_58136789的博客 2万+

ESP32-IDF开发实例-外部Flash与FatFs文件系统数据存取

FatFs是用于小型嵌入式系统的通用FAT / exFAT文件系统模块。FatFs模块是按照ANSI C(C89)编写的,并且与磁盘I/O层完全分开。因此,它独立于平台。它可以并入资源有限的小型微控制器中,例如8051,PIC,AVR,ARM,Z80,RX等。ESP32-IDF对FatFs提供了良好的支持。

视觉与物联智能 2917

详解银行家算法

简述:银行家算法是一种可以避免死锁的方法 就是以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源就相当于用户向银行家贷款。 实现方法: 为保证资金的安全,银行家规定: (1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客; (即当资源池中剩余的可利用资源 >= 线...

weixin_43356265的博客 2万+

【Claude Code 源码解析教程】总体大纲

本教程旨在深入解析 Anthropic Claude Code 项目的源码架构和实现细节。Claude Code 是一个基于 TypeScript + Bun 构建的 AI 编程助手 CLI 工具,代号 "Tengu",具有复杂的多模块架构和丰富的功能特性。本教程基于Claude Code 的源码分析来生成,将帮助您全面掌握 Claude Code 的源码架构和实现细节,为开发类似 AI 编程助手工具奠定坚实基础。

rengang66的博客 387

太空安全卫士:基于YOLOv5的空间态势感知系统(实现轨道碰撞预警与太空环境保护)

做完这个项目,你会发现自己完整走过了“数据采集→标注→模型训练→功能集成→界面开发”的毕设全流程,这不仅是技术能力的证明,更是对“技术守护宇宙安全”这一理念的实践。答辩时,你可以重点讲这几点:系统解决了航天监测的哪些痛点、YOLOv5在太空目标检测中的性能优势、系统未来能怎么优化(比如对接航天监测网络、实现实时轨道预测)。未来,这个系统还能往“更智能”的方向发展:比如结合轨道计算预测碰撞风险、开发移动端APP让天文爱好者参与太空垃圾上报、在航天任务中实现全自动避障决策……想象空间很大。

m0_71589036的博客 90

银行家算法题目详解

知识点 (1)Available【j】=k系统中现有Rj类资源K个 (2)Max【i,j】=k进程i需要Rj类资源最大数目为K个 (3)Allocation【i,j】=k表示进程i当前已分配Rj类资源的数目为K个 (4)need【i,j】=k表示进程i还需要Rj类资源数目K个 need=Max-Allocation 安全性算法举例 假定系统中有5个进程{P0,P1,P2,P3,P4}和三类资源{A,B,C}各种资源的数目分别是10,5,7,T0时刻的资源分配情况如下表 (1)第一步:先利用公式Need=M

m0_46315852的博客 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: 死锁详解
下一篇: ReentrantLock详解
SunSaturday
博客等级 码龄7年 10粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值