死锁算法:银行家算法和安全性算法

2023-11-10

死锁算法:银行家算法和安全性算法

借鉴了一些文章,自己总结了一下

银行家算法

首先,算法的核心在于,每次进程申请资源时,都会进行一次试探性分配,若成功,则真实分配。

基本思想:

  • 在每个新进程进入系统时,他必须声明在运行过程中,可能需要的每种资源类型的最大单元数目(数目不超过系统拥有的资源总量)。
  • 当进程请求一组资源时,系统必须首先在确定是否有足够的资源分配给该进程。
  • 若有,在进一步计算将这些资源分配给进程后,是否会使系统处于不安全状态。如果处于安全状态,才将资源分配给他;否则,让进程等待。

银行家算法中的数据结构

为实现银行家算法,在系统中必须要有这样四个数据结构,分别用来描述系统中可利用的资源,所有进程对资源的最大需求系统中的资源分配,以及所有进程还需要资源的情况

可利用资源 Available:这是一个含有 m 个元素的数组,其中每一个元素代表一类可利用的资源情况。其初始值是系统所配置的全部可用资源的数目。 如果Available[j] = k,则表示系统中现有 Rj 类资源 k 个。

最大需求矩阵 Max:这是一个 nm 的矩阵。它定义了系统中 n 个进程每一个对 m 类资源的最大需求。如果Max[i,j] = K,则表示进程i需要 Rj 类资源的最大数目为 K。

分配矩阵 Allocation:这也是一个 nm 矩阵,它定义了系统中每一类资源当前已分配给每一类进程的资源。如果Allocation[i.j]= K,则表示进程 i 已分得 Rj 类资源的数目为 K。

需求矩阵 Need:当前所有进程还需要的资源

m 的矩阵,用来表示每一个进程尚需的各类资源数,如果Need[i,j]=K,则表示进程 i 还需要 K 个 Rj 类资源才能完成任务

上述三个矩阵之间存在如下关系:Need[i, j] = Max[i, j] - Allocation[i, j]。

名称
可利用资源向量 int Available[m] m为资源种类
最大需求矩阵 int Max [n][m] n为进程的数量
分配矩阵 int Allocation[n][m]
还需资源矩阵 int need[i][j]=Max[i][j]- Allocation[i][j]
申请资源数量 int Request [m] 会一直更新,暂存申请
工作向量 int Work[m] int Finish[n]

算法步骤

1.初始化
2.进程申请资源

(1)数据装入Request

(2)输入合法性判断

如果合计申请超出了之前声明的最大,则报错。如果申请超过了目前可用,则阻塞。

3.试探性分配
for(int i=0;i<m;i++)
{
    available[i] -= request[i];
    allocation[index][i] += request[i];
    need[index][i] -= request[i];
}
4.安全检验

调用安全性算法,如果当前状态时安全的,则正式进行分配。否则,回滚状态,阻塞该进程。

安全性算法

数据结构

工作向量 Work,它表示可以提供给进程继续运行所需要的各类的资源数目,它含有 m 个元素,在执行安全算法开始时,Work = Available

Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。开始先做Finish[i] = false。当有足够资源分配给进程时,再令 FInish[i] = false;

算法思想

a.从进程集合中找到一个满足下述条件的进程:

Finish[i] = false;
Need[i,j]<=Work[j];
如果找到执行步骤 b,否则执行步骤 c;

b.当进程 Pi 获得资源后,可顺利执行,直到完成,并释放它的资源。故应执行:

Work[j] = Work[j] + Allocation[i,j];
Finish[j] =true;
返回执行步骤 a

c.如果所有进程的 Finish[i] = true 都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

更新:完全的实现代码

//
// Created by Zza on 2022/4/15.
//

#ifndef DATASTRUCTUREIMPLEMENTINGC_BANKERRESOURCEDISPATCH_H
#define DATASTRUCTUREIMPLEMENTINGC_BANKERRESOURCEDISPATCH_H

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
//#include <pthread.h>

// init count of resource type
#define M 3
// init count of process
#define N 2

typedef struct Condition{
    int available[M];
//    可选的,主要是在开始的时候初始化用
    int max[N][M];
    int need[N][M];
    int allocation[N][M];
    volatile int request[M];
    int cur;
    int n;
    int m;
} Condition, *pCond;
//int need[i][j] = Max[i][j]- Allocation[i][j]

#define ACT_TIMES 10

typedef struct Actions{
    int processId;
    int request[M];
}Actions, *acts;

// global var
//static Condition CurCond;

bool InitCond(pCond cond);

bool DisplayCurCond(pCond cond);

// Banker actions

bool UpdateCond(pCond, acts);

bool BankerEvaluate(pCond);

bool preAllocate(pCond);

bool RollBack(pCond);

bool Commit(pCond);

//======================================================================================================================

// safety method

typedef struct SafetyWork{
    int work[M];
    bool finished[N];
} sfWork;

bool SafetyCertification(pCond cond);

bool sfWorkInit(sfWork*, pCond);

bool FindAndAlloc(sfWork* jud, pCond cond);

bool EndPhaseJudge(sfWork* jud, pCond cond);

//======================================================================================================================

#ifndef MAIN_FUNC
#define MAIN_FUNC
void test_main(){
    Condition cond;
    InitCond(&cond);
    cond.available[0] = 2;
    cond.available[1] = 4;
    cond.available[2] = 3;
    Actions reqs[] = {
            {0,{2,0,0}},
            {1,{0,1,1}},
            {1,{2,1,2}},
            {1,{0,1,0}},
            {-1,{2,1,0}},
    };
    acts req = reqs;
    while (req->processId >= 0){
        DisplayCurCond(&cond);
        UpdateCond(&cond,req);
        BankerEvaluate(&cond);
        printf("---------\n");
        req++;
    }

}
#endif

//======================================================================================================================

bool InitCond(pCond cond){
    cond->cur = 0;
    cond->n = N;
    cond->m = M;
    for(int i=0;i<N;i++){
        for(int j=0;j<M;j++){
            cond->allocation[i][j] = 0;
            cond->max[i][j] = 2;
            cond->need[i][j] = cond->max[i][j] - cond->allocation[i][j];
            cond->available[j]+=cond->max[i][j];
        }
    }
//    数据初始化
    return 1;
}

bool DisplayCurCond(pCond cond){
    printf("avail: ");
    for(int j=0;j<cond->m;j++){
        printf("%d\t",cond->available[j]);
    }
    printf("\n");
    return 1;
}

//======================================================================================================================

bool BankerEvaluate(pCond cond){
//    输入检验与预分配
    if(!preAllocate(cond))return false;

//    预分配后安全性检验
    if(SafetyCertification(cond)){
        Commit(cond);
        printf("allocation success!\n");
    } else{
        printf("unsafe request, refuse, alloc fail.\n");
        RollBack(cond);
        return false;
    }
    return true;
}

bool preAllocate(pCond cond){
    // 申请检验
    for(int i=0; i<cond->m; i++){
        if(cond->available[i] < cond->request[i] // 是否有剩余的空间给予分配
           ||
           cond->need[cond->cur][i] < cond->request[i]) // 判断是否是合法的申请
        {
            printf("invalid request, allocation fail\n");
            return false;
        }
    }
    // 预分配
    for(int i=0; i<M; i++){
        cond->allocation[cond->cur][i] += cond->request[i];
        cond->need[cond->cur][i] -= cond->request[i];
    }
    return true;
}

bool UpdateCond(pCond cond, acts act){
    cond->cur = act->processId;
    printf("get request of %d:\n",act->processId);
    for(int i=0; i<M; i++){
        printf("%d\t",act->request[i]);
        cond->request[i] = act->request[i];
    }
    printf("\n");
    return 1;
}

bool RollBack(pCond cond){
    for(int i=0; i<M; i++){
        cond->allocation[cond->cur][i] -= cond->request[i];
        cond->need[cond->cur][i] += cond->request[i];
    }
    return 1;
}

bool Commit(pCond cond){
    for(int i=0; i<M; i++){
        cond->available[i] -= cond->request[i];
    }
    return true;
}

//======================================================================================================================

// safety method

bool SafetyCertification(pCond cond){
    sfWork jud;
    sfWorkInit(&jud, cond);
// 首先是找到一个没有完成的进程,把资源全部分配给它
    while (FindAndAlloc(&jud, cond));
    return EndPhaseJudge(&jud,cond);
}

bool sfWorkInit(sfWork* jud, pCond cond){
    for(int i=0;i<M;i++){
        jud->work[i] = cond->available[i];
    }
    for(int i=0;i<cond->n;i++){
        jud->finished[i] = false;
    }
    return 1;
}


bool FindAndAlloc(sfWork* jud, pCond cond){
    for(int i=0, j; i<cond->n; i++){
        if(!jud->finished[i]){
            for(j=0; j<M && cond->need[i][j] < jud->work[j]; j++);
            if(j == M){
                for(j=0; j<M; j++) { jud->work[j] += cond->allocation[i][j]; }
                jud->finished[i] = true;
                return 1;
            }
        }
    }
    return 0;
}

bool EndPhaseJudge(sfWork* jud, pCond cond){
    for(int i=0, j; i<cond->n; i++){
        if(!jud->finished[i]){
            return false;
        }
    }
    return true;
}

#endif //DATASTRUCTUREIMPLEMENTINGC_BANKERRESOURCEDISPATCH_H

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

死锁算法:银行家算法和安全性算法 的相关文章

  • 泛型方法使用

    Java中关于泛型方法中类型变量的确定 首先 在我们使用泛型的时候我们要显示的告诉编译器所要使用的具体类型 比如 新建了一个Integer类型的ArrayList 并在 lt gt 中指明了类型 ArrayList
  • 【GIN】上下文 bind的几种方法

    1 Bind var req vo RegisterRequest ctx Bind req It writes a 400 error and sets Content Type header text plain in the resp

随机推荐

  • VM虚拟机中的web服务内网穿透的设置,虚拟机连接主机的mysql(主机win10 虚拟机win10)

    前言 由于我的主机里环境弄得乱七八糟 无法正常使用阿帕奇 我又不想重置电脑 所以就想在虚拟机里配置环境 结果我的虚拟机无法安装mysql 于是就用虚拟机访问主机的mysql 我在虚拟机里部署的Flask项目 然后WEB服务器用的是阿帕奇2
  • 对于全连接层的理解 全连接层的推导

    全连接层的推导 全连接层的每一个结点都与上一层的所有结点相连 用来把前边提取到的特征综合起来 由于其全相连的特性 一般全连接层的参数也是最多的 全连接层的前向计算 下图中连线最密集的2个地方就是全连接层 这很明显的可以看出全连接层的参数的确
  • 等响度曲线_什么是“响度”

    转自 https blog csdn net weixin 36225384 article details 112220422 原文 https www tonmeister ca wordpress 2014 06 07 bo tech
  • 正则表达式 匹配美元等多种货币符号的超简单方法

    p Sc 带小数点也不怕 Symbol Meaning p a character with the xx property Sc Currency symbol 方法二 暴力匹配 正则表达式 xA2 xA5 u058F u060B u09
  • QT开发之QString转换之路

    编程中少不了字符串的使用 QT提供了QString变量类型 字符串链表可直接使用QStringList进行变量定义和声明 那如果使用了其他表示字符串的变量应该怎么相互转化呢 这里就列举几个常用的几个类型之间的转化 错误之处 还望指出批评 1
  • 蓝桥杯2023模拟赛 滑行题目编号2414

    问题描述 小蓝准备在一个空旷的场地里面滑行 这个场地的高度不一 小蓝用一个 n 行 m 列的矩阵来表示场地 矩阵中的数值表示场地的高度 如果小蓝在某个位置 而他上 下 左 右中有一个位置的高度 严格 低于当前的高度 小蓝就可以滑过去 滑动距
  • 当你在浏览器中输入了网址访问时产生了哪些技术步骤

    当你在浏览器中输入了网址访问时产生了哪些技术步骤 前段时间在知乎上了看一些网络方面的知识 刚好小编自己也是从事这一块的相关工作由对网络方面有一定的了解 今天我们来讲讲 当你在浏览器中输入本站域名并回车后 这背后到底发生来什么事情 因平台原因
  • 如何让IE8及以下版本浏览器支持HTML5新的定义元素?

    如何让IE8及以下版本浏览器支持HTML5新的定义元素 1 我们都知道HTML5在HTML4的基础上 增加了很多新的特性和元素 其中也包括定义元素 比如 header section footer aside nav 但是这些元素在低版本的
  • 记一次个别网站不能访问的问题

    这是天猫的网站 之前我突然电脑不能访问这些网站 我试了很多种办法 都是失败 1 修改用户名 2 修改本地策略 3 后来又把浏览器 包括ie全部设置清除 4 还去选了下自动获取dns 最后我用cmd gt net int ip reset g
  • RuntimeError: CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa, opb

    今天跑一个项目时遇到了如下问题 RuntimeError CUDA error CUBLAS STATUS EXECUTION FAILED when calling cublasSgemm handle opa opb m n k alp
  • 【GUI】LVGL8内存泄漏分析

    LVGL版本 V8 0 2 平台 ESP32S3 在调试过程中 发现有两个界面 在重复退出再进入时内存会不断增加的吃内存现象 然后做了分析和研究 1 样式style吃内存 在主页面 进入simple页面 再退出到主页面 再次进入simple
  • eNSP搭建USG6000V防火墙教程-web

    eNSP搭建USG6000V防火墙教程 web 1 先注册设备 很重要 一定要先注册设备 2 创建USG6000V 3 启动防火墙和连接客户机 3 开启一系列的功能和配置ip 4 避坑指南 1 先注册设备 很重要 一定要先注册设备 2 创建
  • vscode使用json后在浏览器报404not found

    user id 1 show 玲珑骰子安红豆 入骨相思知不知 name 王维 id 2 show 五花马 千金裘 name 李白 id 3 show 仰天大笑出门去 我辈岂是蓬蒿人 name 李白 list 王维 李白 如上是我写的json
  • c语言编程请增补函数fun

    题目 填空题 请增补函数fun 该函数的功能是 把从主函数中输入的字符串str2接在字符串str2的背面 例似 str2 How do str2 you do 结论输出 How do you do 试题程序 include include
  • 第十二届蓝桥杯国赛-H:和与乘积-python

    一 问题描述 二 问题分析 对于输入的一个数列 求这个数列的满足以下条件的区间个数 该区间的元素和与元素积相等 思路就是计算每一个区间的元素和与元素积 如果相等就计数加一 获取每个区间采用前缀和跟前缀积的方法 详见代码 注 这种方法也只能通
  • Sass语法学习

    1 编译监控 自动监控把sass编译成css文件 命令行 sass watch sass basic scss css basic css 在监控的sass后面 可以为 sass 生成 css 样式指定生成的格式 默认是nested型 st
  • 手机端网页:可拖拽悬浮按钮

    div style width 60px height 60px img src im div
  • cesium for unreal文档中的更新

    以前调试过cesium for unreal 再调试时一惊 发现api变了 静下心来思考流程 1 样本条要放在actor里 2 包含样本条的actor坐标放在原点 3 样本条坐标和法向量都要从经纬高到ue空间转换 变的只是api 所以深入了
  • 服务端架构:Mybatis-Plus的优缺点

    前段时间帮朋友处理java后端架构问题 看到了mybatis plus 其实早几年就知道这个东西 但一直没用没学 这两天许久未见的web服务看了看 聊聊个人感受 如有不适 请见谅 文章目录 优点 缺点 1 对数据访问层DAO的上层入侵太强
  • 死锁算法:银行家算法和安全性算法

    死锁算法 银行家算法和安全性算法 借鉴了一些文章 自己总结了一下 银行家算法 首先 算法的核心在于 每次进程申请资源时 都会进行一次试探性分配 若成功 则真实分配 基本思想 在每个新进程进入系统时 他必须声明在运行过程中 可能需要的每种资源