• 银行家算法


               银行家算法:

    银行家算法是一种最有代表性的避免死锁的算法。又被称为“资源分配拒绝”法。

    银行家算法中的数据结构:

    (1)可利用资源向量Available。这是一个含有m个元素的数组,当中的每个元素代表一类可利用的资源数组,其初始值是系统中所配置的该类所有可用资源的数目,其数值随该类资源的分配和回收而动态地改变。

    (2)最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每个进程对m类资源的最大需求。

    (3)分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源。

    (4)需求矩阵Need。这也是一个n*m的矩阵,用以表示每个进程尚需的各类资源数。

     上述三个矩阵间存在下述关系:

                 Need[i,j]=Max[i,j]-Allocation[i,j]

    针对上述数据结构我们能够这样理解:

    首先,我们把操作系统看作“银行家”,操作系统管理的资源看作“银行里的资金”,进程向操作系统请求分配资源相当于“用户向银行家贷款”。

    那么,上述银行家算法中的数据结构能够解释为:

    (1)向量Available是一个含有m个元素的数组,能够看作银行里有m种币种(像人民币,美元,欧元,英镑等)。假设Available[j]=K,则表示最初银行里Rj类币种的钱数为K

    (2)最大需求矩阵Max是一个n*m的矩阵,能够看作用户需贷每种币种的最大数量。假设Max[i,j]=K,则表示第i个用户须要Rj类币种钱数最大为K

    (3)分配矩阵Allocation也是一个n*m的矩阵,表示银行家把银行中每种币种的钱已贷给用户的数量。假设Allocation[i,j]=K,则表示用户i已贷得Rj类币种的数目为K

    (4)需求矩阵Need也是一个n*m的矩阵,表示每个用户还须要再贷每一类币种的数量。假设Need[i,j]=K,则表示用户i还须要Rj类币种的钱数为K

    银行家算法:

    Request[i]是进程Pi的请求向量,假设Request[i][j]=K,表示进程Pi须要KRj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

    (1)假设Request[i][j]<=Need[i,j],便转向步骤(2);否则觉得出错,由于它所需的资源数已超过它所宣布的最大值。

    (2)假设Request[i][j]<=Available[j],便转向(3);否则表示尚无足够资源,Pi需等待。

    (3)系统试探着把资源分配给进程Pi,并改动以下的数据结构中的数值:

             Available[j]:=Available[j]-Request[i][j];

             Allocation[i,j]:=Allocation[i,j]+Request[i][j];

             Need[i,j]:=Need[i,j]-Request[i][j];

    (4)系统运行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,已完毕本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进城Pi等待。

    银行家算法能够这样理解:

    Request[i]是用户Pi的请求向量,假设Request[i][j]=K,表示用户Pi须要Rj类币种的钱的数目为K。当用户提出请求时,银行家按下述步骤进行检查:

    (1)假设Request[i][j]<=Need[i,j],便转向步骤(2);否则觉得出错,由于如今用户所要求贷的钱数超过他原先预定的需贷的钱数。

    (2)假设Request[i][j]<=Available[j],便转向步骤(3);否则表示银行中j类币种的钱数临时已不能满足用户的需求,所以此时用户Pi需等待。

    (3)银行家试探着把各个币种的钱分配给用户。

    (4)银行家再通过安全性算法检查按上述方案能否把各币种的钱贷给用户,假设能,则正式把钱贷给用户,否则,本次试探分配作废,恢复原来银行中各类币种的数量,让用户Pi等待。

    安全性算法:

    系统所运行的安全性算法可描写叙述例如以下:

    (1)设置两个向量:

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

         ②Finish,它表示系统是否有足够的资源分配给进程,使之执行成功。開始时先做Finish[i]:=false;当有足够资源分配给进程时,再令Finish[i]:=true

    (2)从进程集合中找到一个能满足下述条件的进程:

         ①Finish[i]=false

         ②Need[i,j]<=Work;若找到,运行步骤(3),否则,运行步骤(4)。

    (3)当进程Pi获得资源后,可顺利运行,直至完毕,并释放出分配给它的资源,故应运行:

         Work[j]:=Work[j]+Allocation[i,j];

         Finish[i]:=true;

         goto step;

    (4)假设全部进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

    银行家算法代码:<摘自百度百科>

    #include<STRING.H>
    #include<stdio.h>
    #include<stdlib.h>
    #include<CONIO.H>/*用到了getch()*/
    #defineM5/*进程数*/
    #defineN3/*资源数*/
    #defineFALSE0
    #defineTRUE1
    /*M个进程对N类资源最大资源需求量*/
    intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
    /*系统可用资源数*/
    intAVAILABLE[N]={10,5,7};
    /*M个进程已分配到的N类数量*/
    intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
    /*M个进程已经得到N类资源的资源量*/
    intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
    /*M个进程还须要N类资源的资源量*/
    intRequest[N]={0,0,0};
    voidmain()
    {
    inti=0,j=0;
    charflag;
    voidshowdata();
    voidchangdata(int);
    voidrstordata(int);
    intchkerr(int);
    showdata();
    enter:
    {
    printf("请输入需申请资源的进程号(从0到");
    printf("%d",M-1);
    printf("):");
    scanf("%d",&i);
    }
    if(i<0||i>=M)
    {
    printf("输入的进程号不存在,又一次输入!
    ");
    gotoenter;
    }
    err:
    {
    printf("请输入进程");
    printf("%d",i);
    printf("申请的资源数
    ");
    printf("类别:ABC
    ");
    printf("");
    for(j=0;j<N;j++)
    {
    scanf("%d",&Request[j]);
    if(Request[j]>NEED[i][j])
    {
    printf("%d",i);
    printf("号进程");
    printf("申请的资源数>进程");
    printf("%d",i);
    printf("还须要");
    printf("%d",j);
    printf("类资源的资源量!申请不合理,出错!请又一次选择!
    ");
    gotoerr;
    }
    else
    {
    if(Request[j]>AVAILABLE[j])
    {
    printf("进程");
    printf("%d",i);
    printf("申请的资源数大于系统可用");
    printf("%d",j);
    printf("类资源的资源量!申请不合理,出错!请又一次选择!
    ");
    gotoerr;
    }
    }
    }
    }
    changdata(i);
    if(chkerr(i))
    {
    rstordata(i);
    showdata();
    }
    else
    showdata();
    printf("
    ");
    printf("按'y'或'Y'键继续,否则退出
    ");
    flag=getch();
    if(flag=='y'||flag=='Y')
    {
    gotoenter;
    }
    else
    {
    exit(0);
    }
    }
    /*显示数组*/
    voidshowdata()
    {
    inti,j;
    printf("系统可用资源向量:
    ");
    printf("***Available***
    ");
    printf("资源类别:ABC
    ");
    printf("资源数目:");
    for(j=0;j<N;j++)
    {
    printf("%d",AVAILABLE[j]);
    }
    printf("
    ");
    printf("
    ");
    printf("各进程还须要的资源量:
    ");
    printf("******Need******
    ");
    printf("资源类别:ABC
    ");
    for(i=0;i<M;i++)
    {
    printf("");
    printf("%d",i);
    printf("号进程:");
    for(j=0;j<N;j++)
    {
    printf("%d",NEED[i][j]);
    }
    printf("
    ");
    }
    printf("
    ");
    printf("各进程已经得到的资源量:
    ");
    printf("***Allocation***
    ");
    printf("资源类别:ABC
    ");
    for(i=0;i<M;i++)
    {
    printf("");
    printf("%d",i);
    printf("号进程:");
    /*printf(":
    ");*/
    for(j=0;j<N;j++)
    {
    printf("%d",ALLOCATION[i][j]);
    }
    printf("
    ");
    }
    printf("
    ");
    }
    /*系统对进程请求响应,资源向量改变*/
    voidchangdata(intk)
    {
    intj;
    for(j=0;j<N;j++)
    {
    AVAILABLE[j]=AVAILABLE[j]-Request[j];
    ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];
    NEED[k][j]=NEED[k][j]-Request[j];
    }
    }
    /*资源向量改变*/
    voidrstordata(intk)
    {
    intj;
    for(j=0;j<N;j++)
    {
    AVAILABLE[j]=AVAILABLE[j]+Request[j];
    ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];
    NEED[k][j]=NEED[k][j]+Request[j];
    }
    }
    /*安全性检查函数*/
    intchkerr(ints)
    {
    intWORK,FINISH[M],temp[M];
    inti,j,k=0;
    for(i=0;i<M;i++)FINISH[i]=FALSE;
    for(j=0;j<N;j++)
    {
    WORK=AVAILABLE[j];
    i=s;
    while(i<M)
    {
    if(FINISH[i]==FALSE&&NEED[i][j]<=WORK)
    {
    WORK=WORK+ALLOCATION[i][j];
    FINISH[i]=TRUE;
    temp[k]=i;
    k++;
    i=0;
    }
    else
    {
    i++;
    }
    }
    for(i=0;i<M;i++)
    if(FINISH[i]==FALSE)
    {
    printf("
    ");
    printf("系统不安全!本次资源申请不成功!
    ");
    printf("
    ");
    return1;
    }
    }
    printf("
    ");
    printf("经安全性检查,系统安全,本次分配成功。
    ");
    printf("
    ");
    printf("本次安全序列:
    ");
    printf("进程依次为");
    for(i=0;i<M;i++)
    {
    printf("%d",temp[i]);
    printf("->");
    }
    printf("
    ");
    return0;
    }


  • 相关阅读:
    【代码审计】XDCMS 报错注入
    【渗透测试】MS17-010 "永恒之蓝" 修复方案
    【代码审计】MenInfo文件包含漏洞
    【代码总结】数据库抽象层PDO
    【代码总结】PHP面向对象之接口与多态性应用
    【代码总结】PHP面向对象之抽象类
    东哥手把手带你刷二叉树(第一期)
    二叉树的序列化,就那几个框架,枯燥至极
    二叉堆详解实现优先级队列
    递归反转链表的一部分
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3812500.html
走看看 - 开发者的网上家园