操作系统(3)银行家算法模拟实现

参考博客:银行家算法详解(C语言)_Sparky*的博客-CSDN博客_银行家问题c语言

1. 效果展示

2. 程序流程图

3. 数据结构设计

/**定义数据结构*/
vector<vector<int>> Max;// 最大需求矩阵
vector<vector<int>> Allocation; // 已分配矩阵
vector<vector<int>> Need; // 需求矩阵
vector<int> Available; // 资源可用情况
vector<string> Name; // 资源名称
vector<int> Work; // 记录系统中当前各类可用资源的数目
vector<int> Request; // 系统对各类资源请求的数目

4. 功能函数设计

序号

函数

功能说明

1

void print_cover();

打印程序封面

2

void init_data();

初始化进程及资源数据

3

void controller();

程序业务流程控制器

4

void print_menu();

打印菜单命令

5

bool security_detection();

安全性检测

6

void display();

展示当前进程和资源信息

7

int bank_getRequest();

接收用户手动分配资源信息

8

bool bank_check(int id);

检测数据是否符合银行家算法要求

9

void try_allocate(int id);

试分配资源

10

void roll_back(int id);

回滚操作

5. 代码实现

/// 银行家算法模拟实现
#include <bits/stdc++.h>
using namespace std;

/**定义数据结构*/
vector<vector<int>> Max;// 最大需求矩阵
vector<vector<int>> Allocation; // 已分配矩阵
vector<vector<int>> Need; // 需求矩阵
vector<int> Available; // 资源可用情况
vector<string> Name; // 资源名称
vector<int> Work; // 记录系统中当前各类可用资源的数目
vector<int> Request; // 系统对各类资源请求的数目

/**定义全局变量*/
int ProcessNum;// 系统中进程的数量
int ResourceNum;// 资源类型的数量

/**函数声明*/
void print_cover(); //打印系统封面
void init_data(); //初始化进程及资源数据
void controller(); //系统业务流程控制器
void print_menu(); //打印菜单命令
bool security_detection(); //安全性检测
void display(); //展示当前进程和资源信息
int bank_getRequest(); //接收用户手动分配资源信息
bool bank_check(int id); //检测数据是否符合银行家算法要求
void try_allocate(int id); //试分配资源
void roll_back(int id); //回滚操作

int main()
{
    print_cover();
    controller();
    return 0;
}

void print_cover() {
    printf("\t--------------------------\n");
    printf("\t||                      ||\n");
    printf("\t||   银行家算法模拟程序     ||\n");
    printf("\t||                      ||\n");
    printf("\t||                      ||\n");
    printf("\t||             Seven    ||\n");
    printf("\t||                      ||\n");
    printf("\t--------------------------\n");
}

void print_menu() {
    printf("\t-------------------------------------\n");
    printf("\t||                                  ||\n");
    printf("\t||      **手动进行资源请求**           ||\n");
    printf("\t||       1. 查看资源矩阵及分配情况      ||\n");
    printf("\t||       2. 手动请求资源              ||\n");
    printf("\t||       0. 退出程序                 ||\n");
    printf("\t||                                  ||\n");
    printf("\t||                                  ||\n");
    printf("\t-------------------------------------\n");
}

void init_data() {
    // 清空
    Max.clear();
    Allocation.clear();

    // 输入资源信息
    cout<<"请输入可用资源的种类数量:";
    cin>>ResourceNum;

    string  temp_resourceName;
    int temp_resourceNum;
    for(int i=0; i<ResourceNum; i++)
    {
        cout<<"请输入第"<<i+1<<"个可用资源的名称: ";
        cin>>temp_resourceName;
        Name.push_back(temp_resourceName);
        cout<<"请输入初始可用资源"<<Name[i]<<"的数量: ";
        cin>>temp_resourceNum;
        Available.push_back(temp_resourceNum);
    }
    cout<<endl;

    // 输入进程信息
    cout<<"请输入进程的数量:";
    cin>>ProcessNum;
    // 输入Max矩阵
    cout<<"请输入进程的Max矩阵:"<<endl;
    int temp_maxResourceNum;
    vector<int> temp_Max;
    for(int i=0; i<ProcessNum; i++){//遍历每一个进程
        for(int j=0; j<ResourceNum ;j++){ //输入第i个进程中每种资源的数量
            cin>>temp_maxResourceNum;
            temp_Max.push_back(temp_maxResourceNum);
        }
        Max.push_back(temp_Max);
        temp_Max.clear();
    }
    // 输入Allocation矩阵
    cout<<"请输入进程的Allocation矩阵:"<<endl;
    int temp_allocationNum;
    int temp_needNum;
    vector<int> temp_Allocation;
    vector<int> temp_Need;
    vector<int> temp_AllocationSum(ResourceNum); //记录每种资源的已分配数量
    for(int i=0; i<ProcessNum; i++){//遍历每一个进程
        for(int j=0; j<ResourceNum ;j++){ //遍历每一种资源
            cin>>temp_allocationNum;
            temp_Allocation.push_back(temp_allocationNum);
            temp_needNum = Max[i][j] - temp_allocationNum;
            temp_Need.push_back(temp_needNum);
            temp_AllocationSum[j] += temp_allocationNum; //统计已经分配的资源量
        }
        Allocation.push_back(temp_Allocation);
        temp_Allocation.clear();
        Need.push_back(temp_Need);
        temp_Need.clear();
    }

    for(int j=0; j<ResourceNum; j++)//更新可用资源数目Available
    {
        Available[j] = Available[j]-temp_AllocationSum[j];
    }
}

void display() {
    printf("\t--------------------\n");
    printf("\t系统当前可用的资源矩阵Available:\n");
    printf("\t\t");
    for(int i=0; i<ResourceNum; i++) {
        cout<<Name[i]<<"  ";
    }
    printf("\n\t\t");
    for(int i=0; i<ResourceNum; i++)
        cout<<Available[i]<<"  ";

    printf("\n\t--------------------\n");
    printf("\t系统当前资源分配情况如下: \n");
    printf("\t       Max         Allocation        Need\n");
    printf("进程名  ");
    for(int i=0; i<3; i++) {
        for(int j=0; j<ResourceNum; j++) {
            cout<<Name[j]<<"    ";
        }
    }
    cout<<endl;
    for(int i=0; i<ProcessNum; i++){//打印进程
        printf("P%d     ",i);
        for(int j=0; j<ResourceNum; j++){
            printf("%d    ",Max[i][j]);
        }
        for(int j=0; j<ResourceNum; j++){
            printf("%d    ",Allocation[i][j]);
        }
        for(int j=0; j<ResourceNum; j++){
            printf("%d    ",Need[i][j]);
        }
        cout<<endl;
    }
}

int bank_getRequest() {
    printf("请输入希望手动分配资源的进程的编号:");
    int id;
    cin>>id;
    while(true)
    {
        if(id < 0 || id > ProcessNum-1)
            printf("进程不存在!请重新输入\n请输入希望手动分配资源的进程的编号:");
        else break;
        cin>>id;
    }
    printf("请输入请求资源数(%d个):\n", ResourceNum);
    int temp_requestNum;
    for (int i = 0; i < ResourceNum; ++i) {
        cin>>temp_requestNum;
        Request.push_back(temp_requestNum);
    }
    cout<<"请求资源数录入完毕!"<<endl;
    return id;
}

bool bank_check(int id) {
    bool res = true;
    // 判断银行家算法的前置条件是否成立:1. 申请是否大于需求,若大于则出错; 2. 申请是否大于当前可分配资源,若大于则出错
    for (int i = 0; i < ResourceNum; ++i) {
        if(Request[i]>Need[id][i]) {
            printf("进程请求资源数大于所需资源数,无法分配!\n");
            res=false;
            break;
        }
        else if(Request[i]>Available[i]) {
            printf("进程请求资源数大于可用资源数,无法分配!\n");
            res=false;
            break;
        }
    }
    return res;
}

void try_allocate(int id) {
    for (int i = 0; i < ResourceNum; ++i) {
        Available[i] = Available[i] - Request[i];
        Allocation[id][i] += Request[i];
        Need[id][i] -= Request[i];
    }
}
void roll_back(int id) {
    for (int i = 0; i < ResourceNum; ++i) {
        Available[i] = Available[i] + Request[i];
        Allocation[id][i] -= Request[i];
        Need[id][i] += Request[i];
    }
}

void controller() {
    // 保证输入初始数据后,系统是安全的
    while(true) {
        init_data();
        display();
        bool isSecure = security_detection();
        if(isSecure) {
            break;
        } else {
            cout<<"初始数据不合格,请重新输入!"<<endl;
        }
    }

    // 用户选择自主选择手动分配资源或是退出程序
    while (true) {
        print_menu();
        cout<<"请选择手动分配资源或是退出程序:";
//        fflush(stdin);
        int choice;
        cin>>choice;
        if(choice==1)
        {
            display();
        }
        else if(choice==2)
        {
            int id = bank_getRequest();
            if(bank_check(id)){
                printf("开始为进程%d进行资源试分配...\n", id);
                try_allocate(id);
                display();
                if (security_detection()) {
                    cout<<"是否确认分配?(1.确认;2.取消)"<<endl;
                    int op;
                    while(true) {
                        cin>>op;
                        if(op==1) {
                            cout<<"已成功分配!"<<endl;
                            break;
                        } else if(op==2) {
                            roll_back(id);
                            cout<<"已取消分配!"<<endl;
                            break;
                        } else {
                            cout<<"请输入正确指令!(1.确认;2.取消)"<<endl;
                        }
                    }

                }
            }else{
                cout<<"进程请求的资源数不合法,请重试!"<<endl;
            }
        } else if(choice==0) {
            printf("已成功退出,欢迎下次使用银行家算法模拟程序!");
            exit(0);
        } else {
            printf("不存在此指令,请重新输入!\n");
        }
    }
}

bool security_detection() {
    //Finish:系统是否有足够的资源分配给进程,使之完成运行;开始时先令Finish[i]=false,当有足够资源分配给进程时,再令Finish[i]=true
    vector<bool> Finish(ProcessNum, false);
    // 在执行安全算法开始时,Work=Available
    for (int i = 0; i < ResourceNum; ++i) {
        Work.push_back(Available[i]);
    }

    // 开始检测
    int finishedResource = 0; //统计一个进程中有多少种资源可以被满足
    vector<int> SecuritySequence; // 保存进程在安全情况下的执行顺序
    for (int i = 0; i < ProcessNum; ++i) {
        //遍历完一个进程就将count置为0,对新的i号进程资源达标数进行计数
        finishedResource = 0;
        for (int j = 0; j < ResourceNum; ++j) {
            // 如果进程没有执行且资源需求条件满足
            if(!Finish[i] && Need[i][j]<=Work[j]) {
                finishedResource++;
                if(finishedResource==ResourceNum) {
                    Finish[i] = true; //标记进程可执行
                    // 回收Available空间
                    for (int k = 0; k < ResourceNum; ++k) {
                        Work[k] += Allocation[i][k];
                    }
                    SecuritySequence.push_back(i);
                    i = -1; // 从头开始遍历进程
                }
            }
        }
    }

    // 判断系统是否安全
    for (int i = 0; i < ProcessNum; ++i) {
        if (!Finish[i]) {
            cout<<"安全检测警告:系统不安全!"<<endl;
            return false;
        }
    }

    cout<<"安全检测成功:系统此时是安全的!"<<endl;

    // 输出安全序列
    for (int i = 0; i < SecuritySequence.size(); ++i) {
        printf("P%d",SecuritySequence[i]);
        if(i<SecuritySequence.size()-1) {
            printf("-->");
        }
    }
    cout<<endl;
    return true;
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值