《操作系统》银行家算法(C语言版)

银行家算法简述

银行家算法是最有名的避免死锁的策略(区别于死锁的预防)。

该策略以银行的借贷策略为基础建立模型。系统掌握有限个数的资源,用于提供给不同的进程。如果所有进程都能得到他们需要得最大资源数,并运行完成、归还资源,则该系统是安全的。

算法流程描述

1、·首先对进行当前的系统状态进行初始化:先输入系统所拥有的每种资源的数量(Resource)、当前运行的进程对每种资源的最大需求量(MaxNeed)和每个进程已分配到的每种资源的数量(Allocation),就可以计算出每个进程还需要的资源量(Need)及系统还未分配的资源量(Available)。至此,对系统状态的初始化完成。

2、系统进行安全判定。这里用Work保存系统运行中Available的动态过程

先将每个进程的状态(Finish)初始化为0。依次对比Need与Work中资源数目,当Work里的资源能够满足Need中某一进程对资源的需求量时,将Finish里该进程赋值为1,该进程转化为完成时。将该进程释放的资源给Work(Work[j] += Allocation[i][j];),保存进程下标。

若全部进程均运行完成,则系统处于安全状态,输出安全序列。

完整代码:

#include <stdio.h> 
#include<string.h>

#define R 3  //资源数
#define P 4  //进程数

int Resource[R];//资源总量
int Available[R];//还剩下
int MaxNeed[P][R];//每个进程最大需要
int Allocation[P][R];//已分配
int Need[P][R];//还需要
int Work[R];//保存工作时剩余资源数量
int Finish[P];//保存工作过程中进程的状态
int SafeList[P];    //存放安全序列的下标序列 


//初始化:先输入 Resource、MaxNeed和 Allocation,再计算出 Need、Available。   
void Initial(){

    int i, j;
    printf("请分别输入%d种资源的数量:\n",R);
    for (i = 0; i < R; i++) {

        scanf_s("%d", &Resource[i]);
        Available[i] = Resource[i];//目前还未分配,将资源总量与未分配数同步
    }
    printf("当前运行了%d个进程,请输入每个进程对应的%d种资源的最大需求量:\n",P,R);
    for (j = 0; j < P; j++)
        for (i = 0; i < R; i++)
            scanf_s("%d", &MaxNeed[j][i]);
    printf("请输入这%d个进程目前已分配的每种资源的数量:\n",P);
    for (j = 0; j < P; j++)
        for (i = 0; i < R; i++)
            scanf_s("%d", &Allocation[j][i]);

    //计算每个进程还需要的每种资源数量
    for (j = 0; j < P; j++)
        for (i = 0; i < R; i++)
            Need[j][i] = MaxNeed[j][i] - Allocation[j][i];

    //计算每种资源还剩下的资源总量 
    for (j = 0; j < R; j++)
        for (i = 0; i < P; i++)
            Available[j] = Available[j] - Allocation[i][j];

}

//格式化输出
void Printf(int num[R]) {
    int j;

    for (j = 0; j < R; j++) {
        printf("%-4d",num[j]);
        }
    printf("|");
    }
//输出
void PrintState(){
 
    int i,j;
    printf("当前状态:\n|进程|最大需求     已分配       还需要      还剩下      | \n");
    for (i = 0; i < P; i++){

        printf("|P%-3d|",i);
        Printf(MaxNeed[i]);
        Printf(Allocation[i]);
        Printf(Need[i]);
        if (i == 0) {
            Printf(Available);
            printf("\n");
            }
        else
            printf("            |\n");
      }
}


//判断,返回同时满足Finish[i]=0(即进程未运行完成)及Need[i]≤Work的进程号 i,修改i的finish完成状态。
int Judge(){

    int i, j, Rnum;//记资源满足数
    for (i = 0; i < P; i++){
        for (j = 0, Rnum = 0; j < R; j++) {
            if (Finish[i] == 0 && Need[i][j] <= Work[j])
                Rnum++;
            }
        if (Rnum == R) {
            for (j = 0; j < R; j++)
                Work[j] += Allocation[i][j];//获取已完成的进程释放的资源
            Finish[i] = 1;//修改该进程状态
            return i;
            }
    }
    return -1;
}


//检测当前状态是否安全。循环判断,当所有进程均释放完毕,则系统安全,将保存的安全序列输出
int Y_NSafe(){

    int i, SerialNum;//暂存下标
    for (i = 0; i < R; i++)
        Work[i] = Available[i];//还剩下
    memset(Finish,0,sizeof(Finish));

    for (i = 0; i < P; i++){

        for (int j = 0; j < R; j++)
            if (Available[j] < 0) {
                printf("已分配的%d资源数量大于系统所拥有的该资源总量,系统错误\n", j);
                return 0;
                }

        for (int j = 0; j < R; j++){
            if (MaxNeed[i][j] > Resource[j]) {
                printf("%d进程对%d号资源的最大需求数量大于系统所拥有的%d号资源的总量!\n",i,j,j);
                }
            }
        for (int j = 0; j < R; j++) {
            if (Need[i][j] > MaxNeed[i][j]) {
                printf("您请求的%d号资源大于%d进程对%d号资源的最大需求\n",j,i,j);
                }
            }
        SerialNum = Judge();
        //如果进程完成,则将该进程下标存入安全序列
        if (SerialNum >= 0){
            SafeList[i] = SerialNum;
            }
        else 
            return 0;
            }
    

    //判断进程是否全部完成
        return 1;

}


//输出安全序列
void printList(){

    int i0, i, j;
    printf("\n安全序列如下:\n|进程|已分配      |还需要       |还剩下      |\n");
    for (j = 0; j < R; j++){
        Work[j] = Available[j];
    }
    for (i0 = 0; i0 < P; i0++) {
        for (j = 0; j < R; j++) {
            Work[j] += Allocation[SafeList[i0]][j];
            Allocation[SafeList[i0]][j] = 0;
            Need[SafeList[i0]][j] = 0;
            }
        for (i = 0; i < P; i++) {
            printf("|P%-3d|",i);
            Printf(Allocation[i]);
            Printf(Need[i]);
            if (i == 0) 
            Printf(Work);
            printf("\n");
            }
        printf("\n");
        }
}



int main(){

    int i;
    Initial();
    PrintState();
    getchar();

    if (Y_NSafe() == 0){

        printf("当前系统状态不安全\n");
    }else {

        printf("\n当前系统状态安全\n");
        printList();
        
    }
    printf("\n点击回车退出\n");
    getchar();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值