操作系统实验五-操作系统第五次实验银行家算法

个人博客地址

一、实验内容

  • 运用某种高级语言(如C或C++)模拟操作系统第五次实验银行家算法的处理过程。

二、实验目的

  • 操作系统第五次实验银行家算法是避免死锁的代表性算法。本实验旨在加深了解有关资源申请、避免死锁、状态安全性等概念,并体会和运用避免死锁的具体实施方法。然后依照本实验,自行设计模拟程序

三、实验题目

操作系统第五次实验银行家算法的模拟

  • 提示1

    我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源。

    当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。

  • 提示2

    安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。

    不安全状态:不存在一个安全序列。不安全状态一定导致死锁。

    安全序列:一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。

  • 提示3

    设requesti为进程p[i]的请求向量,如果requesti[j]=K,表示进程p[i]需要K个Rj资源。当系统发出请求后,系统按下述步骤开始检查:

    1. 如果requesti[j]<=need[i][j],转向步骤2;否则报告出错,申请的资源已经大于它需要的最大值。

    2. 如果requesti[j]<=available[j],转向步骤3;否则报告出错,尚无足够的资源。

    3. 系统试探着把资源分配给p[i],并修改下列数据结构中的值:

      available[j]=available[j]request[j]
      allocation[i][j]=allocation[i][j]+request[j]
      need[i][j]=need[i][j]-request[j]

    4. 系统进行安全性算法,检查此次分配后,系统是否还处于安全状态,若安全,把资源分配给进程p[i];否则,恢复原来的资源分配状态,让进程p[i]等待。

  • 提示4

    安全性算法:
    int work[RESOURCE_NUMBER];
    bool finish[PROCESS_NUMBER];

    1. Work=Available;
      Finish=false;
    2. 寻找满足条件的i:
      A、Finish[i]=false;
      B、Need[i]≤Work;
      如果不存在,则转4)
    3. Work:=Work+Allocation[i]; Finish[i]:=true;转2
    4. 若对所有i,Finish[i]=true,则系统处于安全状态,
      否则处于不安全状态
  • 提示5

    (操作系统第五次实验银行家算法的程序流程图)

    image-20211128102425394

    思考题

设计本实验时,就尽可能的将设计人性化和考虑全面。如:能不断地进行资源分配;能修改资源的初始状态;提示信息就能充分反映算法过程等。

四、实验设计与过程

数据结构和符号说明
int Available[M],     //每种资源现有的实例数量
    Max[N][M],        //每个进程i的对资源j最大需求
    Allocation[N][M], //每个进程现在所分配的每个资源的实例数量
    Need[N][M],       //每个进程还需要的剩余的资源
    Request[N][M],    //进程资源请求
    sign[N],          //记录安全序列
    process_num,      //进程数量
    recourse_num;     //资源数量
函数说明
void init() //初始化进程资源状况
void print_information() //打印进程资源表
安全性检查算法

算法思路

  1. 初始化Work=Available; Finish=false;
  2. 寻找满足条件的i: A、Finish[i]=false; B、Need[i]≤Work; 如果不存在,则转4)
  3. Work:=Work+Allocation[i]; Finish[i]:=true;同时记录安全序列;转2
  4. 若对所有i,Finish[i]=true,则系统处于安全状态, 否则处于不安全状态
int security_test() //安全性检查
{
    int work[recourse_num];
    bool finish[process_num];
    int count, k = 0;

    for (int i = 0; i < recourse_num; i++) //初始化work
    {
        work[i] = Available[i];
    }
    for (int i = 0; i < process_num; i++) //设置false
    {
        finish[i] = false;
    }
    for (int i = 0; i < process_num; i++) 满足条件释放资源,并从头开始扫描进程集合
    {
        count = 0;
        for (int j = 0; j < recourse_num; j++)
            if (finish[i] == false && Need[i][j] <= work[j])
                count++;
        if (count == recourse_num) //当进程各类资源都满足NEED<=WORK时
        {
            for (int j = 0; j < recourse_num; j++)
                work[j] = work[j] + Allocation[i][j]; //释放进程
            finish[i] = true;
            sign[k] = i; //记录下满足条件的进程
            k++;
            i = -1; //从头开始扫描
        }
    }
    for (int i = 0; i < process_num; i++)
        if (finish[i] == false)
            return 0;
    return 1;
}
操作系统第五次实验银行家算法

算法思路:

  1. 首先进行特殊情况判断

    • 资源不足和申请资源超过最大请求
  2. 然后尝试进行资源分配

    available[j]=available[j]request[j]
    allocation[i][j]=allocation[i][j]+request[j]
    need[i][j]=need[i][j]-request[j]

  3. 系统进行安全性算法,检查此次分配后,系统是否还处于安全状态,若安全,把资源分配给进程p[i];否则,恢复原来的资源分配状态,让进程p[i]等待。

int Banker_Algorithm(int i) //操作系统第五次实验银行家算法
{	//首先进行特殊情况判断
    for (int m = 0; m < recourse_num; m++)
    {
        if (Request[i][m] > Need[i][m])
        {
            cout << "所需资源数超出其宣布的最大值!" << endl;
            return 0;
        }
        else if (Request[i][m] > Available[m])
        {
            cout << "无足够资源,p[" << i << "]需等待!" << endl;
            return 0;
        }
    }
    //尝试为进程分配资源
    for (int j = 0; j < recourse_num; 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];
    }
    cout << "尝试进行资源分配后的进程资源表: " << endl;
    print_information();
    //执行安全性算法
    cout << "正在进行安全性检查" << endl;
    if (security_test())
    {
        cout << "经安全性检查,系统安全,本次分配成功" << endl;
        cout << "安全进程序列为:";
        for (int i = 0; i < process_num - 1; i++)
        {
            cout << "P[" << sign[i] << "]--->";//输出安全的进程序列
        }
        cout << "P[" << sign[process_num - 1] << "]";
    }
    else
    {
        cout << "安全性检测失败!系统不安全!!!正在恢复资源分配------" << endl;
        for (int j = 0; j < recourse_num; 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];
        }
    }
    return 0;
}
完整源代码
#include <bits/stdc++.h>
using namespace std;
#define N 100
#define M 100
int Available[M],     //每种资源现有的实例数量
    Max[N][M],        //每个进程i的对资源j最大需求
    Allocation[N][M], //每个进程现在所分配的每个资源的实例数量
    Need[N][M],       //每个进程还需要的剩余的资源
    Request[N][M],    //进程资源请求
    sign[N],          //记录安全序列
    process_num,      //进程数量
    recourse_num;     //资源数量

void init() //初始化进程资源状况
{
    cin >> process_num >> recourse_num;
    for (int i = 0; i < process_num; i++)
    {
        for (int j = 0; j < recourse_num; j++)
        {
            cin >> Allocation[i][j];
        }
    }
    for (int i = 0; i < process_num; i++)
    {
        for (int j = 0; j < recourse_num; j++)
        {
            cin >> Max[i][j];
            Need[i][j] = Max[i][j] - Allocation[i][j];
        }
    }
    for (int j = 0; j < recourse_num; j++)
    {
        cin >> Available[j];
    }
}
void print_information() //打印进程资源表
{
    cout << "-----------------------------------进程资源表------------------------------------" << endl;
    cout << "|    进程名称   |   已占用资源  |    尚需资源   |  最大所需资源 |  资源剩余实例 |" << endl;
    cout << "|" << setw(16) << "|";
    for (int j = 0; j < 4 * recourse_num; j++)
    {

        cout << setw(4) << char(j % recourse_num + 'A');
        if ((j + 1) % recourse_num == 0)
            cout << "   |";
    }
    cout << endl;
    int k = 0;
    for (int i = 0; i < process_num; i++)
    {
        cout << "|" << setw(10) << "P[" << i << "]"; //进程名称
        cout << "   |";
        for (int j = 0; j < recourse_num; j++)
        {
            cout << setw(4) << Allocation[i][j]; //已占用资源
        }
        cout << "   |";
        for (int j = 0; j < recourse_num; j++)
        {
            cout << setw(4) << Need[i][j]; //尚需资源
        }
        cout << "   |";
        for (int j = 0; j < recourse_num; j++)
        {
            cout << setw(4) << Max[i][j]; //最大所需资源
        }
        if (k == 0)
        {
            cout << "   |";
            for (int j = 0; j < recourse_num; j++)
            {
                cout << setw(4) << Available[j]; //资源剩余实例
            }
            cout << "   |" << endl;
            k = 1;
        }
        else
            cout << "   |" << setw(16) << "|" << endl;
    }
    cout << "---------------------------------------------------------------------------------" << endl
         << endl;
}
int security_test() //安全性检查
{
    int work[recourse_num];
    bool finish[process_num];
    int count, k = 0;

    for (int i = 0; i < recourse_num; i++) //初始化work
    {
        work[i] = Available[i];
    }
    for (int i = 0; i < process_num; i++) //设置false
    {
        finish[i] = false;
    }
    for (int i = 0; i < process_num; i++) 满足条件释放资源,并从头开始扫描进程集合
    {
        count = 0;
        for (int j = 0; j < recourse_num; j++)
            if (finish[i] == false && Need[i][j] <= work[j])
                count++;
        if (count == recourse_num) //当进程各类资源都满足NEED<=WORK时
        {
            for (int j = 0; j < recourse_num; j++)
                work[j] = work[j] + Allocation[i][j]; //释放进程
            finish[i] = true;
            sign[k] = i; //记录下满足条件的进程
            k++;
            i = -1; //从头开始扫描
        }
    }
    for (int i = 0; i < process_num; i++)
        if (finish[i] == false)
            return 0;
    return 1;
}
int Banker_Algorithm(int i) //操作系统第五次实验银行家算法
{
    for (int m = 0; m < recourse_num; m++)
    {
        if (Request[i][m] > Need[i][m])
        {
            cout << "所需资源数超出其宣布的最大值!" << endl;
            return 0;
        }
        else if (Request[i][m] > Available[m])
        {
            cout << "无足够资源,p[" << i << "]需等待!" << endl;
            return 0;
        }
    }
    //尝试为进程分配资源
    for (int j = 0; j < recourse_num; 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];
    }
    cout << "尝试进行资源分配后的进程资源表: " << endl;
    print_information();
    //执行安全性算法
    cout << "正在进行安全性检查" << endl;
    if (security_test())
    {
        cout << "经安全性检查,系统安全,本次分配成功" << endl;
        cout << "安全进程序列为:";
        for (int i = 0; i < process_num - 1; i++)
        {
            cout << "P[" << sign[i] << "]--->";//输出安全的进程序列
        }
        cout << "P[" << sign[process_num - 1] << "]";
    }
    else
    {
        cout << "安全性检测失败!系统不安全!!!正在恢复资源分配------" << endl;
        for (int j = 0; j < recourse_num; 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];
        }
    }
    return 0;
}

int main()
{
    init();
    cout << "初始化进程信息为:" << endl;
    print_information();
    int i, tt = 0;
    while (tt != 999)
    {
        cout << endl
             << "请输入请求资源Request[进程标号i][资源类型j]:" << endl;
        cout << "进程i=:";
        cin >> i;
        cout << "各类资源数量(A B C)=:  ";
        for (int m = 0; m < recourse_num; m++)
            cin >> Request[i][m];
        cout << endl;
        //执行操作系统第五次实验银行家算法
        Banker_Algorithm(i);
        //输出每次判断产生的执行序列
        cout << endl
             << "当前资源分配表:" << endl;
        print_information();
        cout << endl
             << "请输入N(当N=999退出):" << endl;
        cin >> tt;
    }
    return 0;
}
程序初值和运行结果

初值

5 3

0 1 0
2 0 0
3 0 2
2 1 1
0 0 2

7 5 3
3 2 2
9 0 2
2 2 2
4 3 3

3 3 2

首先打印进程初始化信息:

image-20211128171249029

为进程1分配资源(1 0 1)

image-20211128171330517

因为不安全无法分配的情况:

image-20211128173225317

无足够资源需要等待的情况:

image-20211128171404061

申请资源超过其最大请求:

image-20211128171419204

五、实验总结

这次实验模拟了操作系统第五次实验银行家算法,让我更加深刻的理解了进程死锁这一概念,也学习了如何进行死锁预防和死锁避免,而操作系统第五次实验银行家算法正是通过死锁避免来实现的,通过自己编写代码,大大加深了对于操作系统第五次实验银行家算法细节的理解,理解了如何通过安全性算法来检查系统状态是否安全,也更加理解了如何通过资源请求算法来请求资源分配和释放未成功分配的资源。

  • 9
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值