银行家算法【操作系统】实验

XATU jianghong老师 课程设计,银行家算法在云计算服务中的应用可以通过管理和分配计算资源(如 CPU 时间、内存、存储空间)来避免资源冲突和死锁。

如有错误,恳请斧正;制作不易,三连支持。其余问题请私信或评论区留言。

假设有一个云计算服务提供商,它提供了多个虚拟机(VMs)给不同的客户。每个虚拟机可能需要不同的资源量,例如 CPU 核心数、RAM 和磁盘空间。

资源:
  • CPU 核心:50个
  • RAM:200GB
  • 磁盘空间:500GB

【银行家算法通常用于操作系统中,用于在确保安全的情况下进行资源分配,以防止死锁】

在此程序中,银行家算法主要通过以下步骤实现死锁预防:

  1. 资源分配前的安全性检查

    • 在实际分配请求的资源之前,程序使用 CheckSafe 函数来检查分配后的状态是否安全。
    • 它首先创建一个工作数组(work),表示当前可用资源。
    • 然后,程序尝试找到一个安全序列,即一种虚拟机的执行顺序,使得每个虚拟机都可以在其他虚拟机完成并释放资源后获得足够的资源来完成自己的任务。
  2. 模拟分配

    • 在安全性检查过程中,程序模拟分配资源给每个虚拟机,并更新工作数组和完成状态。
    • 如果找到了一个安全序列,这意味着每个虚拟机都可以按顺序完成,不会出现死锁。
    • 如果无法找到安全序列,表示当前的资源请求可能导致死锁,程序将拒绝这个请求。
  3. 保证需求不超过声明的最大值

    • 程序确保任何时候虚拟机的资源请求都不会超过其最初声明的最大需求量。
    • 这有助于防止过度分配资源,从而降低死锁风险。
  4. 保证系统总是处于安全状态

    通过只在保证系统安全的情况下批准资源请求,程序确保系统不会进入可能导致死锁的状态。

该程序的逐步分解如下:

  1. 初始化:首先定义了一些常量和枚举,包括虚拟机的数量(VM_COUNT)、资源类型的数量(RESOURCE_TYPES)以及资源类型(CPU、RAM、DISK)的枚举。还定义了用于存储可用资源、最大需求、当前分配、需求资源以及安全序列的数组。

  2. InputResources():要求用户输入每种资源类型(CPU、RAM、DISK)的总可用资源量。

  3. InputMaxDemand():要求用户输入每个虚拟机对每种资源类型的最大需求。

  4. CheckNeed():检查虚拟机的需求是否可以满足可用资源。

  5. CheckSafe():检查当前的资源分配状态是否安全,即是否存在一种安全的虚拟机执行顺序,可以完成它们的任务而不会导致死锁。

  6. PrintStatus():打印当前的资源分配状态,显示每个虚拟机分配了多少资源。

  7. RequestResources():处理来自特定虚拟机的资源请求。它检查请求是否有效(不超过最大需求或可用资源),以及是否允许请求将系统保持在安全状态。如果请求有效,资源将被分配;否则,请求将被拒绝。

  8. main():在主函数中,程序首先初始化并打印初始的资源分配状态。然后,它进入一个循环,用户可以为特定虚拟机请求资源。程序反复要求输入虚拟机编号和资源请求,处理请求并打印更新后的状态。用户可以选择继续请求资源或退出程序。

程序中的数据结构如下:

  1. Availableint Available[RESOURCE_TYPES]):整数数组,用于表示每种资源类型(CPU、RAM、DISK)的总可用资源量。程序初始化时,用户需要输入这些值。

  2. Maxint Max[VM_COUNT][RESOURCE_TYPES]):二维整数数组,用于表示每个虚拟机对每种资源类型的最大需求量。在程序开始时,用户需要输入这些值。

  3. Allocationint Allocation[VM_COUNT][RESOURCE_TYPES]):二维整数数组,表示当前分配给每个虚拟机的资源数量。在程序执行过程中,这个数组会根据用户的资源请求和释放而更新。

  4. Needint Need[VM_COUNT][RESOURCE_TYPES]):二维整数数组,表示每个虚拟机对每种资源类型的仍然需要的资源量(最大需求减去已分配的部分)。初始时,它与Max数组相同,然后根据资源分配和请求而更新。

  5. SafeOrderint SafeOrder[VM_COUNT]):整数数组,用于存储银行家算法确定的安全执行顺序。如果系统处于安全状态,这个数组将包含虚拟机的执行顺序,以确保没有死锁

  6. int work[RESOURCE_TYPES]:一个整数数组,用于在银行家算法中模拟可用资源的副本。在每次安全性检查时,它会被初始化为实际可用资源的副本,然后根据虚拟机的资源请求和释放来更新。

  7. bool finish[VM_COUNT]:一个布尔数组,用于跟踪每个虚拟机的执行状态。在银行家算法中,如果虚拟机已完成其任务,对应的finish值会被设置为true。

  8. int count:用于计算已完成任务的虚拟机数量。在银行家算法中,当所有虚拟机都已完成任务时,count等于VM_COUNT,表示系统处于安全状态。

  9. int request[RESOURCE_TYPES]:整数数组,用于存储用户输入的资源请求量(CPU、RAM、DISK)。在处理资源请求时,这个数组用于表示虚拟机请求的资源量。

以下是程序代码段(Dev C++运行,非面向对象)

#include <iostream>
#include <limits>
using namespace std;

const int VM_COUNT = 3; // 虚拟机数量
const int RESOURCE_TYPES = 3; // 资源类型数量

enum ResourceType { CPU, RAM, DISK }; // 资源类型枚举

int Available[RESOURCE_TYPES]; // 可用资源数组
int Max[VM_COUNT][RESOURCE_TYPES]; // 最大需求量数组
int Allocation[VM_COUNT][RESOURCE_TYPES]; // 当前分配资源数组
int Need[VM_COUNT][RESOURCE_TYPES]; // 需要资源数组
int SafeOrder[VM_COUNT]; // 安全序列数组

void SafeReadInt(int &value) {
    while (!(cin >> value)) {
        cout << "无效输入,请输入一个数字:" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
}

void InputResources() {
    cout << "请输入每种资源的总量(CPU RAM DISK):" << endl;
    for (int i = 0; i < RESOURCE_TYPES; i++) {
        SafeReadInt(Available[i]);
    }
}

void InputMaxDemand() {
    cout << "请输入每个虚拟机的最大需求量(CPU RAM DISK):" << endl;
    for (int i = 0; i < VM_COUNT; i++) {
        cout << "VM" << i << ": ";
        for (int j = 0; j < RESOURCE_TYPES; j++) {
            SafeReadInt(Max[i][j]);
            Need[i][j] = Max[i][j]; // 初始需求等于最大需求
        }
    }
}

bool CheckNeed(int vm, int work[]) {
    for (int i = 0; i < RESOURCE_TYPES; ++i) {
        if (Need[vm][i] > work[i]) {
            return false;
        }
    }
    return true;
}

bool CheckSafe() {
    int work[RESOURCE_TYPES];
    for (int i = 0; i < RESOURCE_TYPES; ++i) {
        work[i] = Available[i];
    }

    bool finish[VM_COUNT] = {false};
    int count = 0;

    while (count < VM_COUNT) {
        bool found = false;
        for (int i = 0; i < VM_COUNT; ++i) {
            if (!finish[i] && CheckNeed(i, work)) {
                for (int j = 0; j < RESOURCE_TYPES; ++j) {
                    work[j] += Allocation[i][j];
                }
                SafeOrder[count++] = i;
                finish[i] = true;
                found = true;
            }
        }
        if (!found) {
            return false; // 系统不安全
        }
    }
    return true; // 系统安全
}

void PrintStatus() {
    cout << "\n当前资源分配情况:" << endl;
    cout << "VM\tCPU\tRAM\tDISK" << endl;
    for (int i = 0; i < VM_COUNT; ++i) {
        cout << "VM" << i << "\t";
        for (int j = 0; j < RESOURCE_TYPES; ++j) {
            cout << Allocation[i][j] << "\t";
        }
        cout << endl;
    }
}

void RequestResources(int vm, int request[]) {
    cout << "VM" << vm << " 请求资源: CPU=" << request[CPU] << ", RAM=" << request[RAM] << ", DISK=" << request[DISK] << endl;

    // 检查请求是否超过最大需求
    for (int i = 0; i < RESOURCE_TYPES; ++i) {
        if (request[i] > Need[vm][i]) {
            cout << "请求失败:超过最大需求量。" << endl;
            return;
        }
    }

    // 检查请求是否超过可用资源
    for (int i = 0; i < RESOURCE_TYPES; ++i) {
        if (request[i] > Available[i]) {
            cout << "请求失败:资源不足。" << endl;
            return;
        }
    }

    // 尝试分配资源
    for (int i = 0; i < RESOURCE_TYPES; ++i) {
        Available[i] -= request[i];
        Allocation[vm][i] += request[i];
        Need[vm][i] -= request[i];
    }

    // 检查安全性
    if (CheckSafe()) {
        cout << "资源请求成功,系统处于安全状态。" << endl;
    } else {
        cout << "资源请求失败,导致系统不安全。正在撤销请求..." << endl;
        for (int i = 0; i < RESOURCE_TYPES; ++i) {
            Available[i] += request[i];
            Allocation[vm][i] -= request[i];
            Need[vm][i] += request[i];
        }
    }
}

int main() {
    InputResources();
    InputMaxDemand();
    PrintStatus();

    int vm, request[RESOURCE_TYPES];
    char choice = 'y';
    while (choice == 'y' || choice == 'Y') {
        cout << "请输入要请求资源的虚拟机号(0-2):" << endl;
        SafeReadInt(vm);
        if (vm < 0 || vm >= VM_COUNT) {
            cout << "无效的虚拟机号。" << endl;
            continue;
        }

        cout << "请输入 VM" << vm << " 请求的资源量(CPU RAM DISK):" << endl;
        for (int i = 0; i < RESOURCE_TYPES; i++) {
            SafeReadInt(request[i]);
            if (request[i] < 0) {
                cout << "资源请求量不能为负。" << endl;
                goto REQUEST_END;
            }
        }

        RequestResources(vm, request);
        PrintStatus();

        REQUEST_END:
        cout << "是否继续请求资源?(y/n): ";
        cin >> choice;
    }

    return 0;
}

测试用例如下:

初始资源输入:
可用资源(CPU RAM DISK): 50 200 500

虚拟机最大需求量输入:
VM0 最大需求(CPU RAM DISK): 10 40 100
VM1 最大需求(CPU RAM DISK): 20 80 200
VM2 最大需求(CPU RAM DISK): 15 60 150

测试序列:
VM0 请求合理资源:

输入:VM编号 0, 资源请求(CPU RAM DISK): 3 10 20
预期输出:请求成功,系统保持安全状态。
输入非法字符:

输入:VM编号 a 或 @ 等非数字字符
预期输出:提示无效输入,要求重新输入。
VM1 请求过量资源:

输入:VM编号 1, 资源请求(CPU RAM DISK): 50 100 200
预期输出:请求失败,超出最大需求。
VM2 请求可能导致不安全状态的资源:

输入:VM编号 2, 资源请求(CPU RAM DISK): 7 30 75
预期输出:请求失败,导致系统不安全。
VM1 请求负数资源:

输入:VM编号 1, 资源请求(CPU RAM DISK): -2 -5 -10
预期输出:提示资源请求量不能为负。
VM1 请求合理资源(再次测试):

输入:VM编号 1, 资源请求(CPU RAM DISK): 5 20 50
预期输出:请求成功,系统保持安全状态。

结束测试:
输入退出指令(例如输入 n 或 N 当询问是否继续请求资源)。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
5 银行家算法实现 5.1 实验类型 设计型(4学时)。 5.2 实验目的 1) 理解死锁避免相关内容; 2) 掌握银行家算法主要流程; 3) 掌握安全性检查流程。 5.3 实验描述 本实验主要对操作系统中的死锁预防部分的理论进行实验。要求实验者设计一个程序,该程序可对每一次资源申请采用银行家算法进行分配。 5.4 实验内容 1) 设计多个资源(≥3); 2) 设计多个进程(≥3); 3) 设计银行家算法相关的数据结构; 4) 动态进行资源申请、分配、安全性检测并给出分配结果。 5.5 实验要求 1) 编写程序完成实验内容; 2) 画出安全性检测函数流程图; 3) 撰写实验报告。 5.6 测试要求 1) 进行Request请求,输入参数为进程号、资源号和资源数; 2) 进行3次以上的Request请求; 3) 至少进行1次资源数目少于可用资源数,但不安全的请求。 5.7 相关知识 5.7.1 银行家算法的数据结构 1) 可利用资源向量Available。其中每个元素代表每类资源的数目。 2) 最大需求矩阵Max。其中每个元素代表每个进程对于每类资源的最大需求量。Max[i,j]=K表示i进程对于j类资源的最大需求量为K。 3) 分配矩阵Allocation。其中每个元素代表每个进程已得到的每类资源的数目。 4) 需求矩阵Need。其中每个元素代表每个进程还需要的每类资源的数目。 5.7.2 银行家算法 Request i [j]=K表示进程Pi需要K个j类资源。 1) 如果Request i [j]≤Need[i , j],便转向步骤2,否则认为出错。 2) 如果Request i [j]≤Available[j],便转向步骤3,否则表示无足够资源,Pi需等待; 3) 系统尝试分配资源给Pi; 4) 系统进行安全性检查,检查此次资源分配后,系统是否安全。如果安全,则正式分配资源,否则撤销此次分配。 5.7.3 安全性算法 1) 设置两个向量:工作向量Work和Finish。算法开始时Work=Available;Finish表示系统是否有足够的资源分配给进程,使之运行完成,开始时,令Finish[i]=False;如果有足够的资源分配给进程,则令Finish[i]=True。 2) 从进程集合中找到一个能满足下列条件的进程:Finish[i]=False;Need[i,j] ≤ Work[j],若找到,执行步骤3),否则,执行步骤4); 3) Pi获得所需资源后,可顺利执行指导完成,并释放它占有的资源。并执行: Work[j]=Work[j]+Allocation[i , j]; Finish[i] = True; 到第2)步。 4) 直到所有Finish[i]=True,表示系统处于安全状态;否则系统处于不安全状态。 5.8 实验设备 PC机1台,要求安装DOS7.1、Turbo C3.0、Windows2000。 5.9 实验成绩评定 实验成绩评定方式包含实验报告成绩、实验过程成绩两个部分,其中实验过程成绩占60%、实验报告成绩占40%,如果其中任何一个部分成绩不及格,则总成绩按不及格处理。 5.10 实验报告 按照实验目的、实验内容、实验要求、实验设备、测试等部分进行组织。 5.11 实验思考 1) 针对死锁有哪些可行方案? 2) 死锁解除的难点是什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

完成时done

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值