银行家算法

解析银行家算法

#include <stdio.h>
#define R 5 //进程数目
#define C 3 //资源种类 A,B,C
int flag=0;//0没有执行完,1执行完
int Finish[R]={0};

//可用资源数A B C
int WA[3]={17,5,20};
int wa[3]={17,5,20};//存储初值
//最大需求数
int max[R][C]={{5,5,9},{5,3,6},{4,0,11},{4,2,5},{4,2,4}};
//已分配资源数
int allocation[R][C]={{2,1,2},{4,0,2},{4,0,5},{2,0,4},{3,1,4}};
//还需要资源数
int need[R][C];

void putData();
void sub();
void showNeed();

void sub(){
    int request[3];
    int i,j;
    //资源数
    int a,b,c;
    printf("请输入要申请资源的进程号:P");
    scanf("%d",&j);
    printf("\n请输入申请资源数:");
    scanf("%d%d%d",&a,&b,&c);
//判断安全序列
    if(j<R){//进程号符合要求
           if(need[j][0]>=a && need[j][1]>=b && need[j][2]>=c){

                if(a>w[0] || b>w[1] || c>w[2]){
                    printf("请求的资源超出现有资源!!!!!\n请重新输入\n");
                    sub();
                }else{
                    need[j][0]=need[j][0]-a;
                    need[j][1]=need[j][1]-b;
                    need[j][2]=need[j][2]-c;
                    w[0]-=a;
                    w[1]-=b;
                    w[2]-=c;
                    //判断进程是否进行完毕
                    if(need[j][0]==0 && need[j][1]==0 && need[j][2]==0){
                        Flag[j]=1;//标识进程已经结束
                        w[0]+=max[j][0];
                        w[1]+=max[j][1];
                        w[2]+=max[j][2];//统计系统可用资源
                        safe[p++]=j;
                        panduan();
                    }else{
                        panduan();
                    }
                }
           }else if(a>WA[0] || b>WA[1] || c>WA[2]){
                printf("输入的资源数超限,请重新输入\n");
                sub();
            }else{
                printf("输入资源超出所需要的资源数,请重新输入\n");
                sub();
            }

    }else{
        printf("不存在该进程,请重新输入\n");
        sub();
    }

}
//循环判断进程能否进行
int n=0;
void panduan(){
    for(int i=0;i<R;i++){
        if(Flag[i]==0){//判断进程是否进行完毕
            if(need[i][0]<=w[0] && need[i][1]<=w[1] && need[i][2]<w[2]){
                Flag[i]=1;
                w[0]+=max[wait[i]][0];
                w[1]+=max[wait[i]][1];
                w[2]+=max[wait[i]][2];//统计系统可用资源
                safe[p++]=i;
            }else{
                wait[n++]=i;//需要等待的进程
                printf("资源不足,请等待!!\n");
            }
        }
    }
    int x=n;//存放等待进程的数量
    for(;;){
        for(int j=0;j<n;j++){
            if(Flag[wait[j]]==0){//判断进程是否进行完毕
                if(need[wait[j]][0]<=w[0] && need[wait[j]][1]<=w[1] && need[wait[j]][2]<w[2]){
                    Flag[wait[j]]=1;
                    w[0]+=max[wait[j]][0];
                    w[1]+=max[wait[j]][1];
                    w[2]+=max[wait[j]][2];//统计系统可用资源
                    safe[p++]=wait[j];
                    x--;
                }
            }
        }
        //每循环结束进行判断是否还有安全序列
        if(x==n){
            printf("此时刻不存在安全序列!!!!!!\n");
            break;
        }else{
            printf("此刻存在安全序列!!!!!\n");
            for(int k=0;k<R;k++){
                printf("P%d\t",safe[k]);
            }
            printf("\n");
            break;
        }
    }
}

//输出信息
void putData(){
    int i,j;
    printf("资源种类:A\tB\tC\t\n");
    printf("资源数目:%d\t%d\t%d\n",WA[0],WA[1],WA[2]);
    //需求资源s数
    printf("\n各个进程所需资源数:\n\n");
    for(i=0;i<R;i++){
        printf("进程P%d:",i);
        for(j=0;j<C;j++){
            need[i][j]=max[i][j]-allocation[i][j];
            printf("%d\t",need[i][j]);
        }
        printf("\n");
    }//进程提交资源申请数目
}
//输出还需要资源数
void showNeed(){
    int i,j;
    if(flag==1){
        printf("剩余可用资源数:A=%d\tB=%d\tC=%d\n",WA[0],WA[1],WA[2]);
        wa[0]=WA[0];
        wa[1]=WA[1];
        wa[2]=WA[2];
    }else{
        printf("剩余可用资源数:A=%d\tB=%d\tC=%d\n",wa[0],wa[1],wa[2]);
    }
    printf("\n各个进程所需资源数:\n\n");
    for(i=0;i<R;i++){
        printf("进程P%d:",i);
        for(j=0;j<C;j++){
            printf("%d\t",need[i][j]);
        }
        printf("\n");
    }
    sub();
}
int main(){
    putData();
    sub();
}

算法分析
安全状态和不安全状态均指某一时刻的系统状态,,安全状态并不意味着系统不会陷入死锁;不安全状态意味着系统可能会进入死锁,但是不一定,如果在系统的整个运行中一只运用银行家算法保持安全状态,则系统不会陷入死锁,否则在一个时刻存在安全状态是无意义的。可能时刻某个时态从安全状态转变成不安全状态。
此算法最重要的部分就是在申请资源的时刻是否存在安全序列,能否给进程分配资源,一旦不存在安全序列则需要终止本次资源分配,进行存在安全序列的进程分配资源,让每个进程都可以得到资源并且还可以完成进程。
void panduan();方法是判断首次不能进行资源分配的进程,在接下来的资源分配过程中是否可以得到资源,如果循环得不到资源就说明该进程序列不存在安全进程序列。否则就说明该进程序列存在安全序列。
void sub();方法是获取第一次循环时不可以获取资源的序列,其次如果可以获得资源就去判断申请的资源a,b,c和所需要的资源need是否相等,如果相等则说名这个进程是安全的,并且满足了进程所需要的资源,在进程结束后则需要释放资源,这个时候可用资源w增加w+=need,如果没有达到进程需要的资源要求则需要减去申请的资源w-=a,b,c;再次得到可用资源数。
银行计算法基于这样一个原理:如果在系统运行的整个过程中存在一种避免死锁的资源分配方案,则系统就可以顺利推进直至所有进程都进行完毕,反过来,如果进程无法安全进行,则意味着不存在这样一个阻止死锁发生的方案。
如果所有进程的最大资源都小于或者等于系统资源总额,则在银行家算法的作用下,任意时刻都存在安全序列则说明该进程序列时刻都能保持安全状态。深入分析可知:系统的初始状态是安全的那么就说明在这个时刻存在一个安全序列,并且在银行家算法的推进下,这个进程序列可以得到资源并且能继续推进,至少初始状态的安全序列可以将资源合理分配。
如果一个进程在申请了全部可用资源后还无法得到满足,不能及时释放资源,其他进程也无法得到资源,而那个进程一直占用着可用资源,而在这种状态下没有一个可用的安全序列就形成了死锁。但是并不意味着只有一个安全序列,只是利用银行家算法后得到一个最简单的安全序列,更好地利用和分配资源。
关键字:银行家算法、死锁、数据结构

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值