[Operating system] Using C language to implement the banker's algorithm

project environment

Development software: Visual Studio 2019

Programming language: C

Project source code

#include <iostream>
#include <string>

#define MAX_P  50  //最大进程数
#define MAX_R 50  //最大资源数

//银行家算法中的数据结构
int Available[MAX_R];          //可利用资源向量
int Max[MAX_P][MAX_R];          //最大需求矩阵
int Allocation[MAX_P][MAX_R];   //分配矩阵
int Need[MAX_P][MAX_R];         //需求矩阵
int Request[MAX_P][MAX_R];      //进程Pi的请求向量

//安全性算法中的数据结构
int  Work[MAX_R];              //工作向量
bool Finish[MAX_P];           //表示是否有足够的资源分配给进程
int  SafeSeries[MAX_P];        //安全序列

int now_p;                    //当前系统中的进程数
int now_r;                    //当前系统中的资源数

void ShowResourceAllocation();
bool Safety();

//初始化
void Init()
{
    int temp[MAX_R]= { 0 };
    int i, j;
    bool flag = false;
    

    printf("进程总数:");
    scanf("%d", &now_p);
    printf("资源种类数:");
    scanf("%d", &now_r);

    //可利用资源向量的初始化
    printf("%d类资源的当前可利用资源数目:", now_r);
    for (i = 0; i < now_r; ++i)
    {
        scanf("%d", &Available[i]);
    }

    //最大需求矩阵的初始化
    do {
        printf("\n各进程对各资源的最大需求矩阵(%d*%d):\n", now_p, now_r);
        for (i = 0; i < now_p; i++)
        {
            for (j = 0; j < now_r; j++)
            {
                scanf("%d", &Max[i][j]);
                if (Max[i][j] > Available[j])
                    flag = true;
            }
        }
        if (flag)
            printf("警告:资源最大需求量大于系统中资源最大量数,请重新输入!\n");
    } while (flag);

    //分配矩阵的初始化
    do {
        printf("各进程已经分配的资源量(%d*%d):\n", now_p, now_r);
        flag = false;
        for (i = 0; i < now_p; i++)
        {
            for (j = 0; j < now_r; j++)
            {
                scanf("%d", &Allocation[i][j]);
                if (Allocation[i][j] > Max[i][j])
                    flag = true;

                //需求矩阵的初始化
                Need[i][j] = Max[i][j] - Allocation[i][j];

                temp[j] += Allocation[i][j];//统计已经分配给进程的资源数目
            }
        }
        if (flag)
            printf("警告:分配的资源大于最大量,请重新输入!\n");
        } while (flag);

        //目前系统中可利用的资源量
        for (j = 0;j < now_r;j++) {
            Available[j] = Available[j] - temp[j];
        }
        ShowResourceAllocation();//输出当前资源分配情况
}

//输出当前资源分配情况
void ShowResourceAllocation()
{
    int i, j;
    int width = now_r*6;
    printf("系统当前的资源分配情况如下:\n");
    printf("----------------------------------------------------------------------------\n");
    printf("\t%-*s%-*s  %-*s%-*s\n",width, "Max", width,"Allocation", width,"Need", width, "Available");
    printf("进程名\t");
    //输出与进程名同行的资源名
    for (j = 0;j < 4;j++) {
        for (i = 0;i < now_r;i++)
            printf("R%-5d", i);
    }
    printf("\n");
    //输出每个进程的Max、Allocation、Need,和Available
    for (i = 0;i < now_p;i++) {
        printf(" P%d\t", i);
        for (j = 0;j < now_r;j++)
            printf("%-6d", Max[i][j]);
        for (j = 0;j < now_r;j++)
            printf("%-6d", Allocation[i][j]);
        for (j = 0;j < now_r;j++)
            printf("%-6d", Need[i][j]);
        if (i == 0)
        {
            for (j = 0;j < now_r;j++)
                printf("%-6d", Available[j]);
        }
        printf("\n");
    }
}

//是否存在一个安全序列
bool SafetyList() {
    int i, j;
    for (i = 0;i < now_p;i++) {
        if (Finish[i] == false) {
            return false;
        }
    }
    return true;
}

//安全性算法
bool Safety()
{
    int i, j;
    int k = 0;

    //初始化Finish向量
    for (i = 0; i < now_p; ++i)
    {
        Finish[i] = false;  //当系统有足够的资源分配给进程时,值则为true
    }
    //初始化工作向量
    for (j = 0; j < now_r; ++j)
    {
        Work[j] = Available[j];
    }

    //求安全序列
    for (i = 0;i < now_p ;i++) {
        int apply = 0;
        for (j = 0;j < now_r;j++) {
            if (Finish[i] == false && Need[i][j] <= Work[j])
            {
                apply++;
                if (apply == now_r)
                {
                    for (int m = 0;m < now_r;m++)
                        Work[m] = Work[m] + Allocation[i][m];//更改当前可分配资源
                    Finish[i] = true;
                    SafeSeries[k++] = i;
                    i = -1; //保证每次查询均从第一个进程开始
                }
            }
        }
    }
    if (SafetyList())   //调用是否存在安全序列
    {
        printf("系统是安全的\n");
        printf("存在一个安全序列:");
        for (i = 0;i < now_p;i++) {
            printf("P%d", SafeSeries[i]);
            if (i < now_p - 1)
                printf("->");
        }            
        printf("\n");
        return true;
    }
    else
    {
        printf("系统不安全\n");
        return false;
    }
}

//银行家算法
void yhjia()
{
    bool flag = true;//标志变量,判断能否进入银行家算法的下一步
    int  i, j;

    printf("请输入请求分配资源的进程号(0-%d):", now_p - 1);
    scanf("%d", &i);

    printf("请依次输入进程P%d对%d类资源的请求分配量: ", i, now_r);
    for (j = 0; j < now_r; ++j)
    {
        scanf("%d", &Request[i][j]);
    }

    for (j = 0;j < now_r;j++)
    {
        if (Request[i][j] > Need[i][j])//判断申请是否大于需求,若大于则出错
        {
            printf("进程P%d申请的资源大于它需要的资源\n\n", i);
            flag = false;
            break;
        }
        else
        {
            if (Request[i][j] > Available[j])//判断申请是否大于当前可分配资源,若大于则出错
            {
                printf("进程P%d申请的资源大于系统现在可利用的资源\n", i);
                printf("系统尚无足够资源,无法为其分配\n\n");
                flag = false;
                break;
            }
        }
    }
    //前两个条件成立,试分配资源,寻找安全序列
    if (flag)
    {
        for (int j = 0;j < now_r;j++)
        {
            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];
        }
        if (!Safety()) //不存在安全序列
        {
            printf("无法分配,分配完毕后找不到一个安全序列\n");
            for (j = 0; j < now_r; ++j)
            {
                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];
            }
        }
        else //存在安全序列
        {
            //进程需要的资源都满足后,回收资源
            int resources = 0;
            for (j = 0; j < now_r; ++j) {
                if (Need[i][j] == 0) {
                    resources = resources + 1;
                    if (resources == now_r) {
                        for (j = 0; j < now_r; ++j) {
                            Available[j] = Available[j] + Allocation[i][j];
                        }
                    }
                }
            }
        }
    }
    ShowResourceAllocation(); 
}

int main()//主函数
{
    int choice;
    bool flag = true;
    Init();//初始化数据
    
    //判定系统当前时刻是否安全,不安全就不再继续分配资源
    if (!Safety()) 
        exit(0);

    while (flag) {
        printf("\n");
        printf("----------------------银行家算法-------------------\n");
        printf("                     (1):请求分配   \n");
        printf("                     (0):退出       \n");
        printf("---------------------------------------------------\n");
        printf("请选择:");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
            yhjia();break;
        case 0: 
            flag = false;
            break;
        default:
            printf("请输入正确的指令");
        }
    } 
}

result

Guess you like

Origin blog.csdn.net/zhou_ge1/article/details/128646665
Recommended