【附源码】银行家算法(C语言)

银行家算法是一种用于避免死锁的算法,特别适用于资源分配问题。在多道程序设计中,多个进程需要共享有限的资源,如内存、CPU时间片、I/O设备等。银行家算法通过在分配资源时进行安全性检查,确保系统不会进入死锁状态。

一、银行家算法的基本概念

  1. 进程(Process): 请求资源的主体。
  2. 资源类型(Resource Types): 各类资源,如CPU、内存等。
  3. 最大需求矩阵(Max): 每个进程对每种资源的最大需求。
  4. 已分配矩阵(Allocation): 当前已经分配给每个进程的资源。
  5. 需求矩阵(Need) 每个进程还需要的资源,Need[i][j] = Max[i][j] - Allocation[i][j]
  6. 可用资源向量(Available): 当前可供分配的资源总量。
  7. 工作向量(Work): 当前可用的资源,在算法执行中用来模拟资源分配过程。
  8. 完成向量(Finish): 标记进程是否完成,初始值为 false

二、代码

运行效果

完整代码

#include <malloc.h>
 
#include <stdio.h>
 
#include <string.h>
 
#include <windows.h>
 
#define M 3 //资源种类
 
#define N 5 //作业数量
 
#define False 0
 
#define True 1
 
 
char name[N];//资源的名称
 
int Request[N]={0}; //进程的请求资源向量
 
int Resource[M];//各资源总数
 
int Max[N][M];//各进程对各类资源的最大需求
 
int Allocation[N][M];//各进程已分配资源
 
int Need[N][M];//各进程还需要资源
 
int Available[M];//系统可用资源向量
 
int Work[M];//存放系统可提供使用资源,工作向量
 
int Finish[N];//判断安全性标志
 
int temp[N];//存放安全序列的下标序列 list
 
 
void initial()   
 
//创建初始状态:先输入 Resource、Max和 Allocation,再计算出 Need、Available。   
 
{
 
    int i,j;
 
    printf("请输入3种资源的总数量:\n");
 
    for(i=0;i<M;i++)
 
    {
 
        scanf("%d",&Resource[i]);
 
        Available[i]=Resource[i];  // 此时,可利用资源数=总资源数
 
    }
 
    printf("请输入5个进程分别对M种资源的最大需求量:\n");
 
    for(j=0;j<N;j++)
 
        for(i=0;i<M;i++)
 
            scanf("%d",&Max[j][i]); // 最大需求量
 
    printf("请输入N个进程获得M种资源的数量:\n");
 
    for(j=0;j<N;j++)
 
        for(i=0;i<M;i++)
 
            scanf("%d",&Allocation[j][i]);   // 已分配各资源数
 
 
    for(j=0;j<N;j++)
 
        for(i=0;i<M;i++)
 
            Need[j][i]=Max[j][i]-Allocation[j][i];  // 还需资源数
 
    for(j=0;j<M;j++)
 
        for(i=0;i<N;i++)
 
            Available[j]=Available[j]-Allocation[i][j]; // 还可利用资源数
 
}

 
void printState()   
 
//输出当前的状态表
 
{
 
    int i;
 
printf("状态表:\n|Process     |Max         |Allocation  |Need        |Available   | \n");
 
printf("\t     |   %c   %c   %c|   %c   %c   %c|   %c   %c   %c|   %c   %c   %c| \n",name[0],name[1],name[2],name[0],name[1],name[2],name[0],name[1],name[2],name[0],name[1],name[2]);
 
    for(i=0;i<N;i++)
 
    {
 
        if(i==0)
 
            printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|\n",i,Max[i][0],Max[i][1],Max[i][2],Allocation[i][0],Allocation[i][1],Allocation[i][2],Need[i][0],Need[i][1],Need[i][2],Available[0],Available[1],Available[2]);  // 输出11位整型数, 不够11位按左对齐
 
        else
 
            printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|            |\n",i,Max[i][0],Max[i][1],Max[i][2],Allocation[i][0],Allocation[i][1],Allocation[i][2],Need[i][0],Need[i][1],Need[i][2]);
 
    }
 
}
 

 
int isfinish()   
//返回同时满足两个条件{①Finish[i]=false;  ②Need[i][j]≤Work[j]}的进程下标 i(修改Finish[i]=true),否则返回-1。 需求≤可利用
{
 
    int i,j,count;
 
    for(i=0;i<N;i++)   // 计算每个进程finish值
 
    {
 
        for(j=0,count=0;j<M;j++)   
 
            if(Finish[i]==0 && Need[i][j]<=Work[j])  // 仅暂时未分配成功的进程的资源进行判断并计数
 
            {
 
                count++;
 
            }
 
        if(count==3)   // 表示进程中三个资源均可被分配
 
        {
 
            for(j=0;j<M;j++)
 
                Work[j]+=Allocation[i][j];  // 分配
 
            Finish[i]=1;    // 进程可结束
 
            return i;      // 返回新分配资源的进程号
 
        }
 
    }
 
    return -1;
 
}
 
 
int issafe()   
 
//判定当前状态是否为安全状态 (返回 true 或 false),把安全序列的下标放入 List[N]数组。
 
{
 
    int i,a,count=0;
 
    for(i=0;i<M;i++)
 
        Work[i]=Available[i];  // 此时,各资源现可利用数=剩余可利用的各资源数
 
    for(i=0;i<N;i++)
 
        Finish[i]=0;   // 初始化finish[ ]数组,均设为false
 
    for(i=0;i<N;i++)
 
    {
 
        a=isfinish();
 
        if(a!=-1)     // 表示可结束的安全序列下标
 
        {
 
            temp[i]=a;
 
            count++;   // 记录可安全结束的进程数量
 
        }
 
    }
 
    if(count==5)
 
        return 1;      // 存在安全序列
 
    else
 
        return 0;      // 不存在安全序列
 
}
 
 
void printList( )   
 
//输出安全序列表|Process |Work  |Need   |Allocation  |Work+Alloc   |Finish  |
 
{
 
    int i,j;
 
printf("\n安全序列表如下:\n|Process     |Work        |Need        |Allocation  |Work+Alloc  |Finish      |\n");
 
printf("\t     |   %c   %c   %c|   %c   %c   %c|   %c   %c   %c|   %c   %c   %c|\n",name[0],name[1],name[2],name[0],name[1],name[2],name[0],name[1],name[2],name[0],name[1],name[2]);
 
for(j=0;j<M;j++)
 
    {
 
        Work[j]=Available[j];
 
    }
 
    for(i=0;i<N;i++)
 
    {
 
        printf("|P%-11d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|%4d%4d%4d|true\n",temp[i],Work[0],Work[1],Work[2],Need[temp[i]][0],Need[temp[i]][1],Need[temp[i]][2],Allocation[temp[i]][0],Allocation[temp[i]][1],Allocation[temp[i]][2],Work[0]+Allocation[temp[i]][0],Work[1]+Allocation[temp[i]][1],Work[2]+Allocation[temp[i]][2]);
 
        for(j=0;j<M;j++)
 
            Work[j]+=Allocation[temp[i]][j]; 
 
    }
 
}
 

void reqresource(int i, int Request[M])   
 
//表示第 i个进程请求 M类资源 request[M]
 
{
 
    int flag,count1,count2;
    int j;
    //Step1:  判断条件 Request[j]≤Need[i][j]
    for(j=0,count1=0;j<M;j++)
        if(Request[j]<=Need[i][j])
            count1++;
    //Step2:  判断条件 Request[j]≤Available[j]
    for(j=0,count2=0;j<M;j++)
        if(Request[j]<=Available[j])
            count2++;
    if(count2!=3)
        printf("\n尚无足够的资源,第%d个进程堵塞。\n",i);  // 越界
    //Step3:  预先分配
    if(count2==3 && count1==3)  // 未越界
    {
        for(j=0;j<M;j++)
        {
            Available[j]=Available[j]-Request[j];
 
            Allocation[i][j]=Allocation[i][j]+Request[j];
 
            Need[i][j]=Need[i][j]-Request[j];
 
        }    // 预先更新进程i的Available,Allocation,Need状态表
 
        if(issafe()==0)
 
        {
            printf("\n不存在安全序列,不是安全状态。\n");
            for(j=0;j<M;j++)
            {
 
                Available[j]=Available[j]+Request[j];
 
                Allocation[i][j]=Allocation[i][j]-Request[j];
 
                Need[i][j]=Need[i][j]+Request[j];
 
            }   // 恢复进程i的Available,Allocation,Need状态表
        }
        else
        {
            printf("\n是安全序列分配成功!\n");
 
            printList();
        }   
    }
    //Step4:检测是否为安全状态
}
 
int main()
 
{   
 
    int reqid=-1,j;
 
    initial(); // 初始化
 
for(int a=0;a<M;a++){
 
    name[a]=a+65;
 
} // 定义资源名称A,B,C
 
printState();  // 输出状态表
 
    if(issafe()==0)  // 判断安全状态
 
    {
 
        printf("初始状态不安全!\n");
 
    }
 
    else
 
    {
 
        printf("\n初始状态是安全的!\n");
 
        printList(); // 输出安全序列状态表 
 printf("\n"); 
        printf("请输入请求资源进程号(如 1,2,3):");
 
        scanf("%d",&reqid);  // 输入请求资源id号
 
        while(reqid>=0 && reqid<N)   // 判断输入进程 id是否合法 
 
        {
 
            printf("请输入请求资源:");  
 
            for(j=0;j<M;j++)
 
            {
 
                scanf("%d",&Request[j]);
 
            }    // 输入请求资源进程的各资源请求数
 
            reqresource(reqid, Request);  // 进程reqid请求Request[M]资源
 
            printState();
 printf("\n"); 
            printf("请输入请求资源进程号(如 1,2,3):");
 
            scanf("%d",&reqid); 
 
        } 
 
} 
 
return 0;
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值