操作系统银行家算法模拟

1230: 银行家算法

时间限制: 1 Sec  内存限制: 128 MB  Special Judge
提交: 306  解决: 124
[提交] [状态] [讨论版] [命题人:newworldblues]

题目描述

一、实验目的
1、加深理解银行家算法及相关概念。
2、掌握进程申请资源时的安全性检查算法。 
3、能看懂资源分配表(教材p122图3-5)。 

二、实验原理
1、银行家算法原为银行系统设计,以确保银行在发放现金贷款时,不会发生不能满足所有客户需求的情况。银行家算法可以帮助操作系统避免死锁(将客户比作进程,贷款单位比作资源,银行家比作操作系统)。 
2、为实现银行家算法,每个进程必须事先声明自己需要的每种资源类型的最大数目。当进程请求资源时,系统必须确保该进程所拥有的资源数不超过它事先声明最大资源数,同时确保资源请求量不超过当前可用资源量。若两项均满足则执行安全性检查算法。 
3、安全性检查算法用于检查系统进行资源分配后是否安全,若安全,系统才可执行此次分配,否则不执行此次分配。 
4、安全性检查算法:在系统试分配资源后,算法从现有进程列表中寻找出一个可执行进程,回收该进程占用的资源,并寻找下一个可执行进程。若某种执行顺序能够使得所有进程能依次执行,则产生一个安全执行序列,并允许此次资源分配。若进程无法全部执行(无法找到一个安全序列),则本次资源分配将导致系统进入不安全状态,故本次资源请求失败。

三、实验要求
1、用C++语言编写程序,实现银行家算法。
2、main 函数及部分代码已编写如下,只需由你编写 banker 函数并提交。
#include <iostream>
#include <vector>
using namespace std;

void banker(vector<int> &R, vector<vector<int> > &A, vector<vector<int> > &C, vector<vector<int> > &reqestSequence);

int main()
{
    int n, m; // 系统中有 n 个进程、m 种不同类型的资源
    int N; // 进程请求资源的次数
    int i, j;

    cin >> n; // 输入进程数量
    cin >> m; // 输入资源类型数

    vector<int> R(m); // R 向量表示系统中每种资源的的总量

    for (i = 0; i < m; i++) // 对 m 种资源,输入每种资源的总量,保存到向量 R 中
    {
        cin >> R[i];
    }

    vector<vector<int> > C(n, vector<int>(m)); // C 为 Claim 矩阵,即最大需求矩阵,教材上称 Max 矩阵
    for (i = 0; i < n; i++) // 输入 C 矩阵
    {
        for (j = 0; j < m; j++)
        {
            cin >> C[i][j];
        }
    }

    vector<vector<int> > A(n, vector<int>(m)); // A 为 Allocation 矩阵,即分配矩阵
    for (i = 0; i < n; i++) // 输入 A 矩阵
    {
        for (j = 0; j < m; j++)
        {
            cin >> A[i][j];
        }
    }


// 欲针对当前状态做 N 次资源请求测试,故这里一次性输入 N 次资源请求,每次资源请
// 求需要输入 m+1 个整数:第 0 个整数表示申请资源的进程号(取值范围:0 至 n-1);
// 第 1 至 m 个整数分别表示当前状态下,该进程对 m 种资源的申请数量。
    cin >> N; // 输入进程请求资源的次数

    vector<vector<int> > reqestSequence(N, vector<int>(m+1));
    for (i = 0; i < N; i++)
    {
        for (j = 0; j <= m; j++)
        {
            cin >> reqestSequence[i][j];
        }
    }
//

    banker(R, A, C, reqestSequence);

    return 0;
}
 

3、申请资源会出现以下结果:
(1)申请成功
(2)申请失败,因为同意申请会导致系统进入不安全状态
(3)申请失败,其它原因。比如:同意申请将导致该进程获得的资源量大于它声称的最大资源量,或者系统可用资源不足以满足申请,或者两者兼有之。

第(1)种结果,输出0
第(2)种结果,输出1
第(3)种结果,输出2
 

4、同一个状态,可以做无数次申请测试,每次都是基于该状态申请,而不是基于前一次的结果状态申请。以“样例输入”来说,6次资源申请都是在初始状态下申请的,可以理解为对初始状态分别做了6次申请测试,并不是第2次在第1次申请的结果上进行。

四、输入输出格式描述 
以“样例输入、样例输出”为示范,输入输出格式描述如表1所示。 

                                                   表1. 输入输出格式描述

 

输入

4 5
5 2 6 5 3
1 1 2 1 3
2 2 2 1 0
2 1 3 1 0
1 1 2 2 1
1 0 2 1 1
2 0 1 1 0
1 1 0 1 0
1 1 1 1 0
4
0 0 0 0 0 2
1 1 0 0 0 0
2 0 0 3 0 0
3 0 0 1 1 1

 

输出

1
2
2
0
0,2,1
 

 

样例输入

5 3
10 5 7
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
6
1 1 0 2
1 1 2 2
4 3 3 0
0 3 5 1
2 5 0 0
2 5 1 0

 

样例输出

0
1,3,0,2,4
0
3,0,2,4
1
2
2
2

 

代码如下

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

void banker(vector<int> &R, vector<vector<int> > &A, vector<vector<int> > &C, vector<vector<int> > &reqestSequence);

int main()
{
    int n, m; // 系统中有 n 个进程、m 种不同类型的资源
    int N; // 进程请求资源的次数
    int i, j;

    cin >> n; // 输入进程数量
    cin >> m; // 输入资源类型数

    vector<int> R(m); // R 向量表示系统中每种资源的的总量

    for (i = 0; i < m; i++) // 对 m 种资源,输入每种资源的总量,保存到向量 R 中
    {
        cin >> R[i];
    }

    vector<vector<int> > C(n, vector<int>(m)); // C 为 Claim 矩阵,即最大需求矩阵,教材上称 Max 矩阵
    for (i = 0; i < n; i++) // 输入 C 矩阵
    {
        for (j = 0; j < m; j++)
        {
            cin >> C[i][j];
        }
    }

    vector<vector<int> > A(n, vector<int>(m)); // A 为 Allocation 矩阵,即分配矩阵
    for (i = 0; i < n; i++) // 输入 A 矩阵
    {
        for (j = 0; j < m; j++)
        {
            cin >> A[i][j];
        }
    }

    
    // 欲针对当前状态做 N 次资源请求测试,故这里一次性输入 N 次资源请求,每次资源请
    // 求需要输入 m+1 个整数:第 0 个整数表示申请资源的进程号(取值范围:0 至 n-1);
    // 第 1 至 m 个整数分别表示当前状态下,该进程对 m 种资源的申请数量。
    cin >> N; // 输入进程请求资源的次数

    vector<vector<int> > reqestSequence(N, vector<int>(m + 1));
    for (i = 0; i < N; i++)
    {
        for (j = 0; j <= m; j++)
        {
            cin >> reqestSequence[i][j];
        }
    }
    //
    
    banker(R, A, C, reqestSequence);
    system("pause");
    return 0;
}


//R 向量表示系统中每种资源的的总量   C 为 Claim 矩阵,即最大需求矩阵,教材上称 Max 矩阵    A为 Allocation 矩阵,即分配矩阵
void banker(vector<int> &R, vector<vector<int> > &A, vector<vector<int> > &C, vector<vector<int> > &reqestSequence)
{
    int i, j, k;
    int m = R.size();   //m种不同类型资源
    int n = A.size();   //系统中有n个进程
    vector<vector<int> > need(n, vector<int>(m));     //进程还需要的各类资源数  即课本上的need矩阵
    vector<vector<int> > need_temp(n, vector<int>(m)); //进程还需要的各类资源数  need的矩阵的备份
    vector<int> available(m);                        //剩余资源数
    vector<int> work(m);                            //剩余资源数  是available矩阵的备份
    vector<vector<int> > A_temp(n, vector<int>(m)); //已获得的资源数矩阵   A矩阵的备份 A矩阵即为课本allocation矩阵
    available = R;

    for (j = 0; j < m; j++)  //按列遍历  方便计算剩余资源数
    {
        for (i = 0; i <n; i++)
        {
            need[i][j] = C[i][j] - A[i][j];  
            available[j] -= A[i][j];
        }
    }
    
    for (i = 0; i < reqestSequence.size(); i++)  //遍历申请资源的 进程
    {
        work = available;      //备份available矩阵
        need_temp = need;        //备份need矩阵
        A_temp = A;                //备份allocation矩阵

        int w = reqestSequence[i][0];   //获取 当前申请资源的进程号
        int judge = 0;                //若 申请资源后  拥有的资源数  大于宣称最大资源数则judge置1;如果系统剩余资源数不能满足申请则 judge置2, 否则judge=0
        for (j = 0; j < m; j++)
        {
            if (reqestSequence[i][j + 1]>need[w][j])    //本次请求导致所占有资源数大于宣称的最大资源数
            {
                cout <<2<<endl;
                judge = 1;
                break;
            }
        }
        if (judge == 0)
        {
            for (j = 0; j < m; j++)
            {
                if (reqestSequence[i][j + 1]>available[j])   //系统资源不足,无法满足需求
                {
                    cout <<2<<endl;
                    judge = 2;
                    break;
                }
            }
        }
        if (judge == 0)   
        {
            int temp = 1;   //标记位  当前申请资源的进程是否可以直接执行  1可以直接执行;0 表示需要等待
            for (j = 0; j < m; j++)   //假设先给该进程分配资源
            {
                work[j] -= reqestSequence[i][j + 1];   //更新系统剩余资源
                A_temp[w][j] += reqestSequence[i][j + 1];  //更新已分配资源矩阵
                need_temp[w][j] -= reqestSequence[i][j + 1];//更新need矩阵
                if (need_temp[w][j]>0)
                    temp = 0;        //该进程是否需要等待,若need[][]>0 表示 分配给的该进程的资源还未达到 该进程宣称的最大资源 就需要等待
            }                        //need[i][j]=C[i][j]-A[i][j]   C[][]表示宣称最大资源矩阵,即书上的Max矩阵,A[][]表示已分配资源矩阵,即书上的allocation矩阵
            vector<bool> finish(n); //标记进程是否进入安全序列  flase表示还没有进入安全序列   true 表示该进程已经入安全序列
            int ans[100];
            for (j = 0; j < n; j++) //初始状态时,所有进程都没有进入安全序列
            {
                finish[j] = false;   
            }

            if (temp == 1)  //如果该进程可以直接执行,则释放分配给该进程的资源 ,该进程也无需进入安全序列(题目要求)
            {
                for (j = 0; j < m; j++)
                {
                    work[j] += A_temp[w][j];
                    finish[w] = true;
                }
            }

            int flag;
            int time = 0;
            int t = 0;
            while (time<n)     //寻找安全序列
            {
                for (k = 0; k < n; k++)     //遍历进程
                {
                    flag = 1;
                    for (j = 0; j < m; j++)  //flag 为1表示  need[i][j]<=available[j]  否则置0
                    {
                        if (need_temp[k][j]>work[j])
                        {
                            flag = 0;
                            break;
                        }    
                    }
                    if (finish[k] == false && flag==1)  
                    {
                        for (j = 0; j < m; j++)
                        {
                            work[j] += A_temp[k][j];
                        }
                        finish[k] = true;
                        ans[t++] =k;
                        break;
                    }
                }
                time++;
            }
            for (k = 0; k < n; k++)
            {
                if (finish[k] == false)
                    break;
            }
            if (k != n)          //如果没有找到一个安全序列则该资源申请不安全
                cout <<1<<endl;
            else
            {
                cout <<0<< endl;
                for (j = 0; j < t; j++)
                {
                    if (j != 0)
                        cout << ',' << ans[j];
                    else
                        cout << ans[j];
                }
                cout << endl;
            }
        }
    }
}

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值