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

一、实验目的

   1、进一步理解利用银行家算法避免死锁的问题;

2、在了解和掌握银行家算法的基础上,编制银行家算法通用程序,将调试结果显示在计算机屏 幕上,再检测和笔算的一致性。

3、理解和掌握安全序列、安全性算法。

二、实验要求

1、了解和理解死锁;

2、理解利用银行家算法避免死锁的原理;

3、会使用某种编程语言。

三、实验原理

3.1、安全状态

指系统能按照某种顺序如(称为序列为安全序列),为每个进程分 配所需的资源,直至最大需求,使得每个进程都能顺利完成。

3.2、银行家算法

假设在进程并发执行时进程 i 提出请求 j 类资源 k 个后,表示为 Requesti[j]=k。系统按下述步骤进行安全检查:

1)如果 Requesti≤Needi 则继续以下检查,否则显示需求申请超出最大需求值的错误。

2)如果 Requesti≤Available 则继续以下检查,否则显示系统无足够资源,Pi 阻塞等待。

3)系统试探着把资源分配给进程 Pi,并修改下面数据结构中的数值:

Available[j]=Available[j]-Requesti[j]; Allocation[i,j]=Allocation[i,j]+Requesti[j]; Need[i,j]=Need[i,j]-Requesti[j];

4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资 源分配给进程 Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配 状态,让进程 Pi 等待。

3.3、安全性算法

1)设置两个向量:

① 工作向量 Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有 m 个元素, 在执行安全算法开始时,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[i]+Allocation[i,j];

Finish[i]= true;

go to step 2;

4)如果所有进程的 Finish[i]=true 都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。

四、结果展示

正如上课时的PPT所示:

先初始化表格中的Max矩阵、Allocation矩阵、Available矩阵。Need矩阵可由Max与Allocation计算得出。Need=Max-Allocation。

   本次实验的测试数据是5个进程,4种资源,根据测试数据,初始化上述表格:

   初始化以后的表格如下图所示:

   接下来程序会调用安全算法,测试当前状态系统是否安全,测试顺序如下:

   Work=Available,依次判断Need是否小于等于Work,如果小于等于,就分配资源,进程运行完成之后,收回分配给进程的所有资源。再次寻找满足Need小于等于Work的进程,重复上述步骤,直至所有进程的Finish=true,或者剩余的所有进程都不满足Need<=Work的条件。

   由上图所示,所有进程的Finish=true,所以系统是安全的,测试序列就是安全序列。即:

   系统是安全的,因此接下来可以响应部分进程的请求资源申请,假设进程1 request(0,4,2,0),request需满足两个条件:

Request<=available;

Request<=Need.

若同时满足两个条件,就进行预分配:

Available-=Request

Need-=Request

Allocation+=Request

结果如下:

接下来调用安全算法判断当前状态是否安全:

   从结果来看,由于所有进程的Finish=true,所以系统安全,同意分配。安全序列为:

   此时,如果进程1再一次申请资源,假设进程1 Request(0,1,1,0),那么系统将无法提供进程1需要的资源:

五、实验代码

#include <iostream>
using namespace std;

//全局变量定义
int Available[100]; //系统可用资源数组
int Max[50][100];   //进程最大需求数组
int Allocation[50][100];  //进程已分配资源矩阵
int Need[50][100];        //进程还需资源数组
int Request[50][100];     //M个进程还需要N类资源的资源量
int Finish[50];//安全算法中判断是否可以给某个进程分配资源
int safe_sequence[50];//安全序列
int m, n;   //M个进程,N类资源

//安全性算法
int Safe()
{
    int i, j, safe_sequence_length = 0;
    int Work[100]; //可利用资源数组
    int Work1[50][100],Work_Allocation[50][100],Work1_i=0,Work_Allocation_i=0;
    //初始化系统可用资源
    for (i = 0; i < n; i++) {
        Work[i] = Available[i];
    }
    for (i = 0; i < m; i++) {
        Finish[i] = 0;
    }
    for (i = 0; i < m; i++)
    {
        if (Finish[i] == 1) {//找一个Finish[i]!=true的进程
            continue;
        }
        else
        {
            //判断该进程需要的资源是否小于系统可用资源,即找到need<=work的进程
            for (j = 0; j < n; j++)
            {
                if (Need[i][j] > Work[j]) {
                    break;
                }
            }
            //如果找到这样的进程,即当前进程满足need<=work的要求
            if (j == n)
            {
                Finish[i] = 1;
                for (int k = 0; k < n; k++) {
                    Work1[Work1_i][k] = Work[k];//方便可视化
                    Work[k] += Allocation[i][k];//收回该进程已经分配的资源
                    Work_Allocation[Work_Allocation_i][k] = Work[k];//方便可视化
                }
                Work1_i++;//方便可视化
                Work_Allocation_i++;//方便可视化
                safe_sequence[safe_sequence_length++] = i;//当前索引i对应的进程已经获得所需资源,运行结束,将进程PCB号加入安全序列中
                i = -1;
            }
            else {//当前进程不满足need<=work的要求,跳过
                continue;
            }
        }
        //每判断一个进程是否符合need<=work的要求,都要判断安全序列的长度是否为m,即所有的进程都已经满足要求,所有进程的Finish[i]=true
        if (safe_sequence_length == m)
        {
            //安全算法可视化
            cout << "进程\t" << "Work\t\t" << "Need\t\t" << "Alocation\t" << "Work+Alocation  " << "Finish"<< endl;
            for (i = 0; i < m; i++) {
                cout << "P" << safe_sequence[i] << "\t";
                for (int k = 0; k < n; k++) {
                    cout << Work1[i][k] << " ";
                }
                cout << "\t";
                for (int k = 0; k < n; k++) {
                    cout << Need[safe_sequence[i]][k] << " ";
                }
                cout << "\t";
                for (int k = 0; k < n; k++) {
                    cout << Allocation[safe_sequence[i]][k] << " ";
                }
                cout << "\t";
                for (int k = 0; k < n; k++) {
                    cout << Work_Allocation[i][k] << " ";
                }
                cout << "\t";
                if (Finish[i] == 1) {
                    cout << "true" << "\n\n";
                }
                else {
                    cout << "false" << "\n\n";
                }
            }

            cout << "系统是安全的" << '\n';
            cout << "系统安全序列是:\n";
            for (i = 0; i < safe_sequence_length; i++)
            {
                cout << safe_sequence[i];
                if (i != safe_sequence_length - 1)
                    cout << "-->";
            }
            cout << '\n';
            return 1;
        }
    }
    cout << "系统不安全" << endl;
    return 0;
}

//银行家算法
void banker_algorithm() {
    int i, j, process;
    cout << "输入进程的数目:\n";
    cin >> m;
    cout << "输入资源的种类:\n";
    cin >> n;
    cout << "输入每个进程最多所需的各类资源数,按照" << m << "x" << n << "矩阵输入\n";
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            cin >> Max[i][j];
    cout << "输入每个进程已经分配的各类资源数,按照" << m << "x" << n << "矩阵输入\n";
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            cin >> Allocation[i][j];
            Need[i][j] = Max[i][j] - Allocation[i][j];//根据各进程已经分配各类资源的情况,计算各进程还需各类资源的数量
            if (Need[i][j] < 0)
            {
                cout << "你输入的第" << i + 1 << "个进程已经分配第" << j + 1 << "个资源的资源数错误,请重新输入:\n";
                j--;
                continue;
            }
        }
    }
    cout << "请输入各个资源现有的数目:\n";
    for (i = 0; i < n; i++) {
        cin >> Available[i];//输入各类资源的剩余数量
    }

    //银行家算法可视化
    cout << "进程\t" << "Max\t\t" << "Allocation\t" << "Need\t\t" << "Available" << endl;
    for (int i = 0; i < m; i++) {
        cout << "P" << i << "\t";
        for (int j = 0; j < n; j++) {
            cout << Max[i][j]<<" ";
        }
        cout << "\t";
        for (int j = 0; j < n; j++) {
            cout << Allocation[i][j]<<" ";
        }
        cout << "\t";
        for (int j = 0; j < n; j++) {
            cout << Need[i][j]<<" ";
        }
        cout << "\t";
        if (i == 0) {
            for (int j = 0; j < n; j++) {
                cout << Available[j]<<" ";
            }
        }
        cout << "\n\n";
    }

    if (Safe() == 0) {
        return;
    }

    while (1){
        cout << "输入要申请的资源的进程号:(第一个进程号为0,第二个进程号为1,依此类推)\n";
        cin >> process;

        cout << "输入进程所请求的各个资源的数量\n";
        for (i = 0; i < n; i++) {
            cin >> Request[process][i];
        }
        
        //判断是否满足request<=need,request<=available
        for (i = 0; i < n; i++){
            if (Request[process][i] > Need[process][i])//应满足request<=need,进程申请的各类资源数应该小于其所需要的各类资源数
            {
                cout << "所请求资源数超过进程的需求量!\n";
                return;
            }
            if (Request[process][i] > Available[i])//应满足request<=available,进程申请的各类资源数应该小于系统剩余各类资源数
            {
                cout << "所请求资源数超过系统所有的资源数!\n";
                return;
            }
        }

        for (i = 0; i < n; i++)
        {
            Available[i] -= Request[process][i];
            Allocation[process][i] += Request[process][i];
            Need[process][i] -= Request[process][i];
        }

        //银行家算法可视化
        cout << "进程\t" << "Max\t\t" << "Allocation\t" << "Need\t\t" << "Available" << endl;
        for (int i = 0; i < m; i++) {
            cout << "P" << i << "\t";
            for (int j = 0; j < n; j++) {
                cout << Max[i][j] << " ";
            }
            cout << "\t";
            for (int j = 0; j < n; j++) {
                cout << Allocation[i][j] << " ";
            }
            cout << "\t";
            for (int j = 0; j < n; j++) {
                cout << Need[i][j] << " ";
            }
            cout << "\t";
            if (i == 0) {
                for (int j = 0; j < n; j++) {
                    cout << Available[j] << " ";
                }
            }
            cout << "\n\n";
        }

        if (Safe()) {
            cout << "同意分配请求\n";
        }
        else
        {
            cout << "SORRY╮(╯▽╰)╭……你的请求被拒绝…\n";
            //恢复预分配之前各进程分配各类资源的资源数
            for (i = 0; i < n; i++)
            {
                Available[i] += Request[process][i];
                Allocation[process][i] -= Request[process][i];
                Need[process][i] += Request[process][i];
            }
        }
        for (i = 0; i < m; i++) {
            Finish[i] = 0;
        }
        
        char request_again;       //标志位
        cout << "是否再次请求分配?是请按Y/y,否请按N/n:";
        while (1)
        {
            cin >> request_again;
            if (request_again == 'Y' || request_again == 'y' || request_again == 'N' || request_again == 'n') {
                break;
            }
            else{
                cout << "请按要求重新输入:\n";
                continue;
            }
        }
        if (request_again == 'Y' || request_again == 'y') {
            continue;
        }
        else {
            break;
        }
    }
}

int main(){
    banker_algorithm();
    return 0;
}

 

  • 24
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计一个n个并发进程共享m个系统资源的程序以实现银行家算法。要求: 1) 简单的选择界面; 2) 能显示当前系统资源的占用和剩余情况。 3) 为进程分配资源,如果进程要求的资源大于系统剩余的资源,不与分配并且提示分配不成功; 4) 撤销作业,释放资源。 编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁的发生。 银行家算法分配资源的原则是:系统掌握每个进程对资源的最大需求量,当进程要求申请资源时,系统就测试该进程尚需资源的最大量,如果系统中现存的资源数大于或等于该进程尚需求资源最大量时,就满足进程的当前申请。这样就可以保证至少有一个进程可能得到全部资源而执行到结束,然后归还它所占有的全部资源供其它进程使用。 银行家算法中的数据结构 (1)可利用资源向量Available(一维数组) 是一个含有m个元素,其中的每一个元素代表一类可利用的资源数目,其初值是系统中所配置的该类全部可用资源数目。如果Available[j]=k, 表示系统中现有Rj类资源k个。 (2)最大需求矩阵Max(二维数组) m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k, 表示进程i需要Rj类资源的最大数目为k。 (3)分配矩阵Allocation(二维数组) m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation(i,j)=k, 表示进程i当前已分得Rj类资源k个。 (4)需求矩阵Need (二维数组) 是一个含有n*m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need(i,j)=k, 表示进程i还需要Rj类资源k个,方能完成其任务。 Need(i,j)= Max(i,j)-Allocation(i,j)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值