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

news2024/11/25 14:40:21

参考博客:银行家算法详解(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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/102073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小白如何入门Python爬虫?这是我见过最详细的入门教学

本文针对初学者&#xff0c;我会用最简单的案例告诉你如何入门python爬虫&#xff01; 想要入门Python 爬虫首先需要解决四个问题 熟悉python编程 了解HTML 了解网络爬虫的基本原理 学习使用python爬虫库 01了解什么是爬虫&#xff0c;它的基本流程是什么&#xff1f; 网络…

IDEA 2022 之 Lombok 使用 教程

文章目录**1.Lombok是什么****1.1 Lombok 是什么&#xff1f;****Lombok 引入**2、POM 中引入依赖3、IDE 中安装插件**4. Lombok 使用****4.1 Lombok 使用注意**5.代码案例&#xff1a;**Lombok 原理**6. 常用注解结语1.Lombok是什么 ​ Lombok是使用java编写的一款开源类库。…

【Redis】Redis缓存穿透、缓存雪崩、缓存击穿详解与解决办法(Redis专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

Java项目:springboot大学生实习管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本系统的用户可以分为三种&#xff1a;管理员、教师、学生。三种角色登录后会有不同菜单界面&#xff1b; 管理员主要功能&#xff1a; 信息管…

graalvm 拯救生命,速速入手

graalvm 拯救生命&#xff0c;速速入手 标题很夸张&#xff0c;graalvm怎么就拯救生命了&#xff1f;把一个启动5-6秒的项目加速到3秒启动&#xff0c;不就是在拯救生命&#xff0c;拯救发际线吗&#xff1f; 我在上一篇博客"SpringBoot3.0工程建立"末尾启动了工程…

高级网络应用复习——三层热备生成树速端口OSPF实验(带命令)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.知识点总结 路由器热备份技术HSRP &#xff08;思科私有 HS…

学web前端开发和学习其他编程语言一样吗?

前言&#xff1a; web前端是编程中门槛较低&#xff0c;较易入门的&#xff0c;对年龄和学历要求也不是特别高&#xff0c;但如果学历过低&#xff0c;年龄比较大&#xff0c;又完全没有基础&#xff0c;会在学习时感到吃力&#xff0c;另外也会因为用人公司对学历和年龄的限制…

电巢:半导体投资锐减库存调整消费者需求疲软,半导体下行周期何时结束?

前言 投行PitchBook的资料显示截止到本月5日&#xff0c;2022 年全球半导体初创企业的风险投资达到 78 亿美元。与去年创纪录的 145 亿美元投资者注入硅公司的资金相比下降了 46%&#xff0c;与 2020年的103 亿美元相比下降了 24%。 高盛&#xff08;Goldman sachs&#xff09;…

【LSTM回归预测】基于灰狼算法优化长短时记忆GWO-LSTM时序时间序列数据预测(含前后对比)附Matlab代码

​✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法…

Mycat(8):分片详解之取模

1 找到conf/schema.xml修改 2 取模的路由规则 和轮询一样&#xff0c;取模有什么好处&#xff0c;有什么坏处&#xff1f; 优点&#xff1a;利用的写的负载均衡效果&#xff0c;写入速度很快 缺点&#xff1a;批量写入&#xff0c;失败后事务的回滚有难度&#xff01;代表写…

Svelte 带来哪些新思想?赶紧学起来!

本文介绍 点赞 关注 收藏 学会了 Svelte 是我用过最爽的框架&#xff0c;就算 Vue 和 React 再强大&#xff0c;生态再好&#xff0c;我还是更喜欢 Svelte&#xff0c;因为它开发起来真的很爽。 其实在很久之前我就注意到 Svelte &#xff0c;但一直没把这个框架放在心上。…

【Python百日进阶-数据分析】Day133 - plotly饼图:px.pie()实例

文章目录四、实例4.1 带有 plotly express 的饼图4.1.1 欧洲大陆的人口4.1.2 带有重复标签的饼图4.1.3 使用 px.pie 设置饼图扇区的颜色4.1.4 对离散颜色使用显式映射4.1.5 自定义使用 px.pie 创建的饼图4.1.13 Dash 中的饼图四、实例 饼图是一种圆形统计图表&#xff0c;它被…

微服务框架 SpringCloud微服务架构 服务异步通讯 50 消息可靠性 50.2 消息持久化

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯50 消息可靠性50.2 消息持久化50.2.1 消息持久化50 消息可靠性 50.2 消息持久化 50.2.1 消息…

深入解析CSS (3)Flexbox

Flexbox&#xff0c;全称弹性盒子布局 给元素添加display: flex&#xff0c;该元素变成了一个弹性容器&#xff08;flex container&#xff09;&#xff0c;它的直接子元素变成了弹性子元素&#xff08;flex item&#xff09;。 弹性子元素默认是在同一行按照从左到右的顺序并…

[附源码]计算机毕业设计Python的黄河文化科普网站(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

2022年全球IB百强名校出炉,19所香港学校上榜

教育界有句话&#xff1a;“得教育者得天下&#xff0c;得IB者得教育。” 作为目前国际上认可度最高、真正无国界全球通用的、且旨在培养最全面人才的国际课程&#xff0c;IB课程正在为越来越多的学校和家长所青睐。 近日&#xff0c;Best Schools 最新公布了2022年全球最佳IB学…

卷积神经网络-高级篇Advanced-CNN

卷积神经网络-高级篇Advanced-CNN 在基础篇中我们学习了一个简单的CNN 下面介绍其他几个网络结构 GoogLeNet 蓝色为卷积&#xff0c;红色是池化&#xff0c;黄色是softmax输出&#xff0c;绿色是一些拼接层。 在这个大型的网络结构中我们需要做到的是减少代码冗余&#xff0…

为什么Python是2023最值得学的编程语言?

对于那些从来没有学习编程小伙伴&#xff0c;Python 是最好的选择之一&#xff0c; Python 是一种清晰的语言&#xff0c;用缩进来表示程序的嵌套关系可谓是一种创举&#xff0c;把过去软性的编程风格升级为硬性的语法规定。再不需要在不同的风格间选择、再不需要为不同的风格…

阿里工作7年被裁,3个月逆袭字节跳动测试开发,有些心里话想对大家说...

被裁之路 先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入阿里&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;我失去了在阿里5年的工作。虽然有事先通风&#xff0c;但是我没有想到这一天会来的那么快。今天中午收到消息说我们这个组…

网络入门基础

目录 一.预备知识 1.1网络背景 1.2协议 二.网络协议 2.1协议分层 2.2OSI 7层 2.3TCP/IP五层(或四层) 三.网络传输基本流程 3.1局域网通信 3.2 跨网络通信 3.3IP地址与MAC地址 一.预备知识 1.1网络背景 独立模式&#xff1a;计算机之间相互独立 网络互联&#xff1a; 计…