银行家算法(c语言实现)

银行家算法(c语言实现)银行家算法是资源和死锁避免的算法,由艾兹格·迪杰斯特拉(EdsgerDijkstra)设计的算法用于测已确定总数量的资源分配的安全性,在决定是否该分配应该被允许并进行下去之前,通过“s-state”校验码测试资源分配活动期间产生死锁条件的可能性。     该算法是为为THE操作系统设计并且最在在EWD108描述。当一个新的进程进入系统时,进程必须声明所需每个资源实例最大的数量和类型。显然,资…

大家好,又见面了,我是你们的朋友全栈君。

银行家算法是资源和死锁避免的算法,由艾兹格·迪杰斯特拉(Edsger Dijkstra) 设计的算法用于测已确定总数量的资源分配的安全性,在决定是否该分配应该被允许并进行下去之前,通过“s-state”校验码测试资源分配活动期间产生死锁条件的可能性。 
    该算法是为为THE操作系统设计并且最在在EWD108描述。当一个新的进程进入系统时,进程必须声明所需每个资源实例最大的数量和类型。显然,资源数量不不能超过系统最大的资源数。与此同时,进程获得的资源必须在有限的时间内释放。

 

资源

 

对于银行家算法的实现,需要知道三件事: 

  • 每个进程所能获取的每种资源数量是多少[MAX] 
  • 每个进程当前所分配到的每种资源的数量是多少[ALLOCATED] 
  • 系统当前可分配的每种的资源数量是多少[AVAILABLE]

 

只有当资源满足以下条件,资源才会被分配:

  1. request <= max, 也可设置错误条件,当进程所请求的资源超过最大的要求
  2. request <= available, 或者进 
    程一直等直到资源可分配

一些资源在实际的系统被跟踪,如:内存,信号量以及接口。

    银行家算法名字源于该算法实际上是用于确保银行系统不会用尽系统资源,因为当银行系统不再满足所有客户的需求,系统将不会分配钱(看作资源)给客户,银行必须确保对钱的请求不会导致银行系统处于不安全状态。如果上述情况不会发生,则该情况下请求是被允许的,否则,客户必须等到其他客户往银行存进足够银行分配的资金。

基本数据结构用于维护运行银行家算法: 
用n表示系统资源数量,m表示系统资源类型。则我们需要以下的数据结构: 

  • Available: 长度为m的向量用来表示每种资源可分配的数量。如果available[j]=k, 资源类型为Rj可分配数量为k。 
  • Max: n * m矩阵,定义,每个进程最大的资源需求。如果Max[i,j]=k. 表明Pi对类型为Rj资源的请求为k. 
  • Allocation: n * m矩阵定义每个进程已分配到的每种资源的数量。如果Allocation[i,j] = k,进程Pi已分配到类型为Rj的资源数量为k。 
  • Need: n * m 矩阵表明每个进程所需的资源数量,如果Need[i,j] = k, 进程Pi需要至少得到k数量的资源Rj,才能完成任务。

 

公式:Need[i,j] = Max[i,j] – Allocation[i,j]

例子:

系统资源总数: 
A B C D 
6 5 7 6

系统可分配资源数: 
A B C D 
3  1 1 2

进程 (当前分配到的资源数): 
    A B C D 
P1 1 2 2 1 
P2 1 0 3 3 
P3 1 2 1 0

进程 (最大资源需求数): 
    A B C D 
P1 3 3 2 2 
P2 1 2 3 4 
P3 1 3 5 0

Need= Max – Allocation 
进程 (需要的资源数): 
    A B C D 
P1 2 1 0 1 
P2 0 2 0 1 
P3 0 1 4 0

 

安全和不安全状态

 

    如果该状态下所有进程都可以结束运行,则该状态是安全。因为系统无法知道什么时候一个进程结束运行,或有多少资源被进程请求,系统只是假设所有的进程最终会试图获取他们所规定的最大资源,并且在获得资源使用完之后会结束运行。在大多数的情况下,该假设是很合理的,因为系统不会特别的关心每个进程的运行多久(至少不是从死锁避免的角度)。

    对于该猜想,算法确定是否一个状态是安全通过找到一个猜想性的进程请求序列,允许所有进程获取最大的资源数并顺利结束运行。而任何无法达到上诉要求的的状态都是不安全的状态。

    我们可以得到之前例子的安全状态,只要能使每个进程获得最大资源并结束运行。

1.P1 得到 2 A,1 B 和 1 D,达到进程需求的最大资源数 

  • [可分配资源:<3 1 1 2> – <2 1 0 1> = <1 0 1 1>] 
  • 系统当前有1 A, 0 B, 1 C, 和 1 D 资源可分配

 

2.P1 结束运行,释放3 A, 3 B, 2 C, 和2 D资源给系统。 

  • [可分配资源:<1 0 1 1> – <3 3 4 4> = <4 3 3 3>] 
  • 系统当前有4 A, 3 B, 3 C, 和 3 D 资源可分配

 

3.P2 结束运行,请求0 A, 2 B, 0 C, 和1 D资源,之后运行结束,释放资源给系统 

  • [可分配资源:<4 3 3 3> – <0 2 0 1> + <1 2 3 4>= <5 3 6 6>] 
  • 系统当前有5 A, 3 B, 6 C, 和 6 D 资源可分配

 

4.P3 请求0 A, 1 B, 4 C, 和0 D资源,之后运行结束,释放资源给系统 

  • [可分配资源:<5 3 6 6> – <0 1 4 0> + <1 3 5 0>= <6 5 7 6>] 
  • 系统现在用所有的资源6 A, 5 B, 7 C 和 6 D

 

5.由于所有的进程可以结束运行,该状态是安全的状态。

 

请求

 

    当系统收到对资源请求信号时,系统运行银行家算法判断允许请求是否安全。

1.该请求是否可以运行? 

  • 如果不允许,该请求则是不可行的,必须要么拒绝请求或插入到等待队列。 
    2.假设请求被允许 
    3.是否安全? 
  • 如果安全,请求授予 
  • 否则,要么拒绝或插入到等待队列

 

不论系统拒绝请求或请求延迟或不安全请求都是系统的特殊决定。

例子:

从之前的例子开始,假设进程3请求2个单位的资源C。 
1. 系统没有足够的资源C可以用于分配 
2. 该请求被拒绝

另一方面,假设进程3请求1单元资源C。 
1. 系统有足够的资源分配 
2. 请求允许 
新的状态如下:

系统可分配的资源 
       A B C D 
Free 3 1 0 2 
进程 (当前进程分配到资源): 
     A B C D 
P1 1 2 2 1 
P2 1 0 3 3 
P3 1 2 2 0 
进程(最大需求资源数): 
     A B C D 
P1 3 3 2 2 
P2 1 2 3 4 
P3 1 3 5 0

  1. 判断是新的安全状态是否安全 
    1>P1 获得2 A,1 B, 和 1 D资源并运行结束 
    2>之后,P2 能获得2 B 和1 D资源并结束运行 
    3>最后P3 能获得1 B 和3 C资源并运行结束 
    4>因此,改新状态为安全的

最后,从该状态开始,假设进程2请求1单元的资源B。 
1.系统有足够的资源 
2.假设所有的请求都允许,新状态如下:

系统可分配的资源: 
       A B C D 
Free 3 0 1 2 
进程 (当前进程分配到资源): 
    A B C D 
P1 1 2 2 1 
P2 1 1 3 3 
P3 1 2 1 0 
进程(最大需求资源数): 
    A B C D 
P1 3 3 2 2 
P2 1 2 3 4 
P3 1 3 5 0

1.存在安全的状态吗?假设P1,P2,P3请求资源B 和 C。 

  • P1无法完成资源B的请求 
  • P2无法完成资源B的请求 
  • P3无法完成资源B的请求 
  • 没有进程能获得足够的资源结束运行,故该状态是不安全的。

 

/*PROGRAM TO IMPLEMENT BANKER'S ALGORITHM
  *   --------------------------------------------*/
#include <stdio.h>
int curr[5][5], maxclaim[5][5], avl[5];
int alloc[5] = {0, 0, 0, 0, 0};
int maxres[5], running[5], safe=0;
int count = 0, i, j, exec, r, p, k = 1;

int main()
{
    printf("\nEnter the number of processes: ");
    scanf("%d", &p);

    for (i = 0; i < p; i++) {
        running[i] = 1;
        count++;
    }

    printf("\nEnter the number of resources: ");
    scanf("%d", &r);

    printf("\nEnter Claim Vector:");
    for (i = 0; i < r; i++) { 
        scanf("%d", &maxres[i]);
    }

    printf("\nEnter Allocated Resource Table:\n");
    for (i = 0; i < p; i++) {
        for(j = 0; j < r; j++) {
            scanf("%d", &curr[i][j]);
        }
    }

    printf("\nEnter Maximum Claim Table:\n");
    for (i = 0; i < p; i++) {
        for(j = 0; j < r; j++) {
            scanf("%d", &maxclaim[i][j]);
        }
    }

    printf("\nThe Claim Vector is: ");
    for (i = 0; i < r; i++) {
        printf("\t%d", maxres[i]);
    }

    printf("\nThe Allocated Resource Table:\n");
    for (i = 0; i < p; i++) {
        for (j = 0; j < r; j++) {
            printf("\t%d", curr[i][j]);
        }

        printf("\n");
    }

    printf("\nThe Maximum Claim Table:\n");
    for (i = 0; i < p; i++) {
        for (j = 0; j < r; j++) {
            printf("\t%d", maxclaim[i][j]);
        }

        printf("\n");
    }

    for (i = 0; i < p; i++) {
        for (j = 0; j < r; j++) {
            alloc[j] += curr[i][j];
        }
    }

    printf("\nAllocated resources:");
    for (i = 0; i < r; i++) {
        printf("\t%d", alloc[i]);
    }

    for (i = 0; i < r; i++) {
        avl[i] = maxres[i] - alloc[i];
    }

    printf("\nAvailable resources:");
    for (i = 0; i < r; i++) {
        printf("\t%d", avl[i]);
    }
    printf("\n");

    //Main procedure goes below to check for unsafe state.
    while (count != 0) {
        safe = 0;
        for (i = 0; i < p; i++) {
            if (running[i]) {
                exec = 1;
                for (j = 0; j < r; j++) {
                    if (maxclaim[i][j] - curr[i][j] > avl[j]) {
                        exec = 0;
                        break;
                    }
                }
                if (exec) {
                    printf("\nProcess%d is executing\n", i + 1);
                    running[i] = 0;
                    count--;
                    safe = 1;

                    for (j = 0; j < r; j++) {
                        avl[j] += curr[i][j];
                    }

                    break;
                }
            }
        }
        if (!safe) {
            printf("\nThe processes are in unsafe state.\n");
            break;
        } else {
            printf("\nThe process is in safe state");
            printf("\nAvailable vector:");

            for (i = 0; i < r; i++) {
                printf("\t%d", avl[i]);
            }

            printf("\n");
        }
    }
}

/*SAMPLE  OUTPUT
-----------------
Enter the number of processes:5

Enter the number of resources:4

Enter Claim Vector:8 5 9 7

Enter Allocated Resource Table:
2 0 1 1
0 1 2 1
4 0 0 3
0 2 1 0
1 0 3 0

Enter Maximum Claim Table:
3 2 1 4
0 2 5 2
5 1 0 5
1 5 3 0
3 0 3 3

The Claim Vector is:    8   5   9   7
The Allocated Resource Table:
    2   0   1   1
    0   1   2   1
    4   0   0   3
    0   2   1   0
    1   0   3   0

The  Maximum Claim Table:
    3   2   1   4
    0   2   5   2
    5   1   0   5
    1   5   3   0
    3   0   3   3

 Allocated resources:   7   3   7   5
 Available resources:   1   2   2   2

Process3 is executing

 The process is in safe state
 Available vector:  5   2   2   5
Process1 is executing

 The process is in safe state
 Available vector:  7   2   3   6
Process2 is executing

 The process is in safe state
 Available vector:  7   3   5   7
Process4 is executing

 The process is in safe state
 Available vector:  7   5   6   7
Process5 is executing

 The process is in safe state
 Available vector:  8   5   9   7

 ---------------------------------------------------------*/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/131995.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pytest指定用例_文件夹排列顺序自定义

    pytest指定用例_文件夹排列顺序自定义前言测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果.有些同学在写用例的时候,用例写了先后顺序,有先后顺序后,后面还会有新的问题(如:上个用例返回

    2022年7月30日
    4
  • WPF数据采集与监控系统实战开发全记录【附源码 典藏版】[通俗易懂]

    WPF数据采集与监控系统实战开发全记录【附源码 典藏版】[通俗易懂]作为B站学习区非知名Up主,本人酷爱沉迷上位机无法自拔!人称”上位机大王“(滑稽)长期为大家提供各类WPF/上位机学习干货是我的信条!元旦在即,我又连肝一周,录制了一批WPF数据采集与监控系统项目开发实战!!录制内容,从上位机应用基础架构出发,全程代码实战,涉及内容包括串口通信、基础组件开发、用户控件动画、全局静态数据绑定等等。从无到有,完整实操,项目整体以MVVM思想模式设计开发,代码功能使用分层结构,逻辑与View解耦。认真看完全部视频,你可以了解到基本的串口通信方式,以及如何利用WPF的特性开发

    2022年6月8日
    38
  • 复位信号 rst

    复位信号 rstaltera的触发器是低电平触发,所以建议使用rst_n,xilinx的触发器是高电平触发,所以建议使用rst,如果是rst_n,则会增加额外的非逻辑xilinx推荐:由于rst是一个高扇出网络,所以要尽量减少rst的使用,扇出太大会导致时序收敛困难。参考:https://blog.csdn.net/maowang1234588/article/details/103510605根据ff初始值和敏感信号列表中是否有rst(异步触…

    2022年10月1日
    0
  • MySQL数据库:常见经典SQL语句

    MySQL数据库:常见经典SQL语句

    2021年10月4日
    52
  • 搭建nginx rtmp流媒体服务器(超详细)_nginx rtmp 集群

    搭建nginx rtmp流媒体服务器(超详细)_nginx rtmp 集群简单的直播搭建流程本微博在借鉴其他大牛之后,觉得应该写一个直播的完整流程,虽然简单,但是会有一个宏观感受:搭建nginx服务器工具:nginx下载地址:https://nginx.org/download/nginx-1.13.6.zipnginx-rtmp-module-master.zip下载地址:https://github.com/arut/nginx-rtmp-mo

    2022年9月2日
    3
  • 3D游戏建模的入门学习方法及技巧

    3D游戏建模的入门学习方法及技巧选一个你感兴趣的模型利用你感兴趣的任何物品或形象的预制模型。选一个可以激发你想象,让你知道清楚知道自己的模型该是什么样子,该怎么动的模型。你可以根据自己的喜好和需要加强现有模型。预制模型可以让你在开始建模之前,体验模型的检查和操作。从简单模型入手从复杂3D模型入手,你可能会备受打击。选一个简单的结构,然后开始学习。你不仅想要学会3D建模的基本知识,还需要慢慢学习掌握不同的工具、技巧。瓶子一样的圆柱体是一个很好的入门模型。或者你可以用更简单的立方体来熟悉所有工具技巧的用法。复杂模型可能会.

    2022年5月20日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号