银行家算法

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <iomanip>

using namespace std;

//测试数据
//请输入参与的进程数量:4
//请输入参与的资源数量:3
//请输入系统中A资源的数量:9
//请输入系统中B资源的数量:3
//请输入系统中C资源的数量:6
//请输入各进程对各资源的最大需求量:
//3 2 2 6 1 3 3 1 4 4 2 2
//请输入各进程当前已分得各资源的数量:
//1 0 0 5 1 1 2 1 1 0 0 2

int n=100; // 进程数
int m=100; // 资源种类数
int Available[100]={0};     // 可用资源
int Max[100][100]={0};        // 最大需求
int Allocation[100][100]={0}; // 已分得资源
int Need[100][100]={0};       // 需求矩阵
int Work[100]={0};          // 工作向量
bool Finish[100]={0};       // 是否满足
int Request[100]={0};       // 请求资源
char Name[100]={0};     // 资源名称 eg:A B C ...
int P=0;                // 请求资源的进程

void init();
bool safeCheck(bool flag);
void printTable();
void recoverSafe();
void bankerMethod();

// 初始化进程和资源
void init()
{
    cout << "请输入参与的进程数量:";
    cin >> n;
    cout << "请输入参与的资源数量:";
    cin >> m;
    for(int i=0;i<26;i++)
    {
        Name[i]=i+65;
    }
    for(int j=0;j<m;j++)
    {
        //cout << "请输入第" << i+1 << "个资源的名称:";
        //cin >> Name[i];
        cout << "请输入系统中" << Name[j] << "资源的数量:";
        cin >> Available[j];
    }
    cout << "请输入各进程对各资源的最大需求量:" << endl;
    for(int k=0;k<n;k++)
        for(int l=0;l<m;l++)
            cin >> Max[k][l];
    cout << "请输入各进程当前已分得各资源的数量:" << endl;
    for(int i1=0;i1<n;i1++)
        for(int j=0;j<m;j++)
            cin >> Allocation[i1][j];
    for(int i2=0;i2<n;i2++)
        for(int j=0;j<m;j++)
            Need[i2][j]=Max[i2][j]-Allocation[i2][j];
    // 初始化Available
    for(int i3=0;i3<n;i3++)
        for(int j=0;j<m;j++)
            Available[j]=Available[j]-Allocation[i3][j];
    // 初始化Work
    recoverSafe();
}

// 安全性检查
bool safeCheck(bool flag)
{
    //cout << "---DATA---|" << "----Work---|" << "----Need---|" << "-Allocation|" << "Work+Allocation|" << "--Finish--|" << endl;
      //cout << "-RESOURCE-|" << "--A--B--C--|" << "--A--B--C--|" << "--A--B--C--|" << "---A---B---C---|" << endl;
    cout << "---DATA---|" << setfill(' ') << setw(3*m+2) << "Work" << "|" << setw(3*m+2) << "Need" << "|" << setw(3*m+2) << "Allocation" << "|" << setw(3*m+2) << "Work+Allo" << "|" << "Finish|" << endl;
    
    cout << "-RESOURCE-|";

    for(int i=0;i<m;i++)
        cout << "--" << Name[i];
    cout << "--|";
    for(int i1=0;i1<m;i1++)
        cout << "--" << Name[i1];
    cout << "--|";
    for(int i2=0;i2<m;i2++)
        cout << "--" << Name[i2];
    cout << "--|";
    for(int i3=0;i3<m;i3++)
        cout << "--" << Name[i3];
    cout << "--|" << endl;

    number0:
    for(int i4=0;i4<n;i4++)
    {
        int count=0;
        for(int j=0;j<m;j++)
        {
            if(!Finish[i4] && Need[i4][j]<=Work[j])
            {
                count++;
            }
            if(count==m)
            {
                cout << "----P" << i4 << "----|";
                for(int k=0;k<m;k++)
                    cout << "-" << setw(2) << Work[k];
                cout << "--|";
                for(int k1=0;k1<m;k1++)
                    cout << "-" << setw(2) << Need[i4][k1];
                cout << "--|";
                for(int k2=0;k2<m;k2++)
                    cout << "-" << setw(2) << Allocation[i4][k2];
                cout << "--|";

                for(int k3=0;k3<m;k3++)
                {
                    Work[k3]=Work[k3]+Allocation[i4][k3];
                }
                Finish[i4]=true;

                for(int k4=0;k4<m;k4++)
                    cout << "-" << setw(2) << Work[k4];
                cout << "--|";
                cout << "--" << Finish[i4] << "--|";
                cout << endl;
                goto number0;
            }
        }
    }
    for(int i5=0;i5<n;i5++)
    {
        if(!Finish[i5])
        {
            flag=false;
            break;
        }
    }
    if(flag)
    {
        cout << "**系统处于安全状态**" << endl;
        return true;
    }
    else
    {
        cout << "**系统处于不安全状态**" << endl;
        return false;
    }
}

// 打印进程请求后资源分配表
void printTable()
{
    cout << "---DATA---|" << setw(4*m) << "Max" << "|" << setw(4*m) << "Allocation" << "|" << setw(4*m) << "Need" << "|" << setw(4*m) << "Available" << "|" << endl;
    
    cout << "-RESOURCE-|";

    for(int i=0;i<m;i++)
        cout << "-" << Name[i] << "--";
    cout << "|";
    for(int i1=0;i1<m;i1++)
        cout << "-" << Name[i1] << "--";
    cout << "|";
    for(int i2=0;i2<m;i2++)
        cout << "-" << Name[i2] << "--";
    cout << "|";
    for(int i3=0;i3<m;i3++)
        cout << "-" << Name[i3] << "--";
    cout << "|" << endl;

    for(int i4=0;i4<n;i4++)
    {
        cout << "---P" << i4 << "-----|";
        for(int j=0;j<m;j++)
        {
            cout << "-" << setfill('0') << setw(2) << Max[i4][j] << "-";
        }
        cout << "|";
        for(int j1=0;j1<m;j1++)
        {
            cout << "-" << setfill('0') << setw(2) << Allocation[i4][j1] << "-";
        }
        cout << "|";
        for(int j2=0;j2<m;j2++)
        {
            cout << "-" << setfill('0') << setw(2) << Need[i4][j2] << "-";
        }
        cout << "|";
        if(i4==0)
        {
            for(int j3=0;j3<m;j3++)
                cout << "-" << setfill('0') << setw(2) << Available[j3] << "-";
            cout << "|";
        }
        cout << endl;
    }
}

// 安全性检查后,恢复Work向量和Finish向量
void recoverSafe()
{
    // 恢复Work
    for(int i=0;i<m;i++)
        Work[i]=Available[i];
    for(int i1=0;i1<n;i1++)
        Finish[i1]=false;
}

// 银行家算法
void bankerMethod()
{
    // 客户端提示
    cout << "请输入需要请求资源的进程编号(int型):" << endl;
    for(int i=0;i<n;i++)
    {
        cout << setfill(' ') << setw(3) << "P" << i << ": " << i << endl;
    }
    // 检查输入合法性
    int tmpP=-1;
    bool flagP=false;
    while(!flagP){
        cout << "进程编号:";
        scanf("%d",&tmpP);
        if(tmpP<0 || tmpP>=n){
            cout << "此进程不存在,请重新输入!" << endl;
            flagP=false;
            //防止不断循环
            while (getchar()!='\n');
        } else {
            P=tmpP;
            flagP=true;
        }
    }

    // 确认请求资源Request
    for(int i1=0;i1<m;i1++)
    {
        cout << "请输入进程P" << P << "请求的" << Name[i1] << "资源的数量:";
        cin >> Request[i1];
    }

    // 1.判断进程请求数量是否小于需求最大数量
    bool flag=true;
    int countRN=0;
    for(int i2=0;i2<m;i2++)
    {
        if(Request[i2]<=Need[P][i2])
            countRN++;
        if(countRN==m)
            flag=true;
        else
            flag=false;
    }
    if(flag)
    {
        // 2.判断进程请求数量是否小于系统可用数量
        int countRA=0;
        for(int i=0;i<m;i++)
        {
            if(Request[i]<=Available[i])
                countRA++;
            if(countRA==m)
                flag=true;
            else
                flag=false;
        }
        if(flag)
        {
            // 3.系统试探着把资源分配给进程
            for(int i=0;i<m;i++){
                Available[i]=Available[i]-Request[i];
                Allocation[P][i]=Allocation[P][i]+Request[i];
                Need[P][i]=Need[P][i]-Request[i];
                Work[i]=Work[i]-Request[i];
            }
            // T0时刻的资源分配表
            cout << "-----------------------为P" << P << "分配资源后的资源分配表------------------------" << endl;
            printTable();
            // 4.安全性算法
            cout << "------------------------P" << P << "申请资源时的安全性检查-------------------------" << endl;
            flag=safeCheck(flag);

            // 如果安全性检查不通过,则回收进程请求的资源
            if(!flag)
            {
                for(int i=0;i<m;i++){
                    Available[i]=Available[i]+Request[i];
                    Allocation[P][i]=Allocation[P][i]-Request[i];
                    Need[P][i]=Need[P][i]+Request[i];
                    Work[i]=Work[i]+Request[i];
                }
            }
            recoverSafe();
        }
        else
            cout << "**系统中没有足够资源**" << endl;
    }
    else
        cout << "**请求已超出进程P" << P << "需求最大值**" << endl;
}

int main(int argc, char* argv[])
{
    // 初始化进程和资源
    cout << "********************************初始化进程和资源********************************" << endl;
    init();
    cout << "**********************************初始化已完成**********************************" << endl;
    
    // T0时刻的资源分配表
    cout << "---------------------------T0时刻的资源分配表----------------------------" << endl;
    printTable();

    // T0时刻的安全性检查
    cout << "---------------------------T0时刻的安全性检查----------------------------" << endl;
    // 恢复安全性检查向量
    recoverSafe();

    // 银行家算法
    while(true)
    {
        cout << "是否要继续请求资源(y/n):" << endl;
        char ynRequest;
        cin >> ynRequest;
        if(ynRequest=='n' || ynRequest=='N')
            break;
        bankerMethod();
    }

    return 0;
}

银行家算法中使用到的数据结构

  1. 可利用资源数组(Available)
  2. 进程最大需求矩阵(Max)
  3. 分配矩阵(Allocation)
  4. 需求矩阵(Need)

总体步骤

  1. 如果request < need 则转向步骤2,否则出错,因为进程所申请的资源数已经超过了它所需要的资源数。
  2. 如果request < available 则转向步骤3,否则,表示系统中没有足够的资源满足进程pi的申请,pi必须等待。
  3. 尝试把系统的资源分配给pi,并修改下面数据结构中的数值

Available[i]=Available[i]-Request[i];

Allocation[P][i]=Allocation[P][i]+Request[i];

Need[P][i]=Need[P][i]-Request[i];

  1. 系统执行安全性检测算法,检查此次尝试分配后,系统是否处于安全状态。如果安全,则正是把资源分配给进程pi,完成本次分配;否则将尝试是分配作废,系统恢复原来资源分配的状态,让pi等待。

安全性检查步骤

  1. .设两个数组work 和 finish,其中

work表示系统可提供给进程继续运行的各类资源的空闲数目,它包含m个元素,执行安全算法开始时,work[i]= available[i]。

finish表示系统是否有足够的资源分配给进程,使之运行完成,开始时finish[i]=false;当有足够资源分配给进程pi时,使finish[i]=true。

  1. .从进程集合中找出资源满足下述条件的进程:

finish[i]=false;Need[i] < work;

如果找到,则执行步骤(3),否则执行步骤(4)

  1. .当进程pi获得资源后,可顺利执行知道完毕,并释放出分配给它的资源,所以应执行:

Work[i] = Work[i] + Allocation[i];

Finish[i] = true;

goto Step 2;

  1. .如果所有进程的Finish都为True,则表示系统处于安全状态;否则表示系统处于不安全状态。

程序执行结果

********************************初始化进程和资源********************************

请输入参与的进程数量:4

请输入参与的资源数量:3

请输入系统中A资源的数量:9

请输入系统中B资源的数量:3

请输入系统中C资源的数量:6

请输入各进程对各资源的最大需求量:

3 2 2 6 1 3 3 1 4 4 2 2

请输入各进程当前已分得各资源的数量:

1 0 0 5 1 1 2 1 1 0 0 2

**********************************初始化已完成**********************************

---------------------------T0时刻的资源分配表----------------------------

---DATA---|         Max|  Allocation|        Need|   Available|

-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|

---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-01--01--02-|

---P1-----|-06--01--03-|-05--01--01-|-01--00--02-|

---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|

---P3-----|-04--02--02-|-00--00--02-|-04--02--00-|

---------------------------T0时刻的安全性检查----------------------------

是否要继续请求资源(y/n):

y

请输入需要请求资源的进程编号(int型):

  P0: 0

  P1: 1

  P2: 2

  P3: 3

进程编号:3

请输入进程P3请求的A资源的数量:1

请输入进程P3请求的B资源的数量:1

请输入进程P3请求的C资源的数量:0

-----------------------为P3分配资源后的资源分配表------------------------

---DATA---|         Max|  Allocation|        Need|   Available|

-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|

---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-00--00--02-|

---P1-----|-06--01--03-|-05--01--01-|-01--00--02-|

---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|

---P3-----|-04--02--02-|-01--01--02-|-03--01--00-|

------------------------P3申请资源时的安全性检查-------------------------

---DATA---|       Work|       Need| Allocation|  Work+Allo|Finish|

-RESOURCE-|--A--B--C--|--A--B--C--|--A--B--C--|--A--B--C--|

**系统处于不安全状态**

是否要继续请求资源(y/n):

y

请输入需要请求资源的进程编号(int型):

  P0: 0

  P1: 1

  P2: 2

  P3: 3

进程编号:1

请输入进程P1请求的A资源的数量:1

请输入进程P1请求的B资源的数量:0

请输入进程P1请求的C资源的数量:1

-----------------------为P1分配资源后的资源分配表------------------------

---DATA---|         Max|  Allocation|        Need|   Available|

-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|

---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-00--01--01-|

---P1-----|-06--01--03-|-06--01--02-|-00--00--01-|

---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|

---P3-----|-04--02--02-|-00--00--02-|-04--02--00-|

------------------------P1申请资源时的安全性检查-------------------------

---DATA---|       Work|       Need| Allocation|  Work+Allo|Finish|

-RESOURCE-|--A--B--C--|--A--B--C--|--A--B--C--|--A--B--C--|

----P1----|- 0- 1- 1--|- 0- 0- 1--|- 6- 1- 2--|- 6- 2- 3--|--1--|

----P0----|- 6- 2- 3--|- 2- 2- 2--|- 1- 0- 0--|- 7- 2- 3--|--1--|

----P2----|- 7- 2- 3--|- 1- 0- 3--|- 2- 1- 1--|- 9- 3- 4--|--1--|

----P3----|- 9- 3- 4--|- 4- 2- 0--|- 0- 0- 2--|- 9- 3- 6--|--1--|

**系统处于安全状态**

是否要继续请求资源(y/n):

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值