银行家算法

#include <iostream>
#include <string>

#define M 3   //资源的种类数
#define N 5   //进程的个数
char safeSeries [N];
using namespace std;
void output(int iMax[N][M], int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N]);			// 输出打印
bool safety(int iAllocation[N][M], int iNeed[N][M], const int iAvailable[M], const char cName[N]);							// 安全性算法
bool banker(int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N]);							// 银行家算法

int main()
{
    int i, j;

    //当前可用每类资源的资源数
    int iAvailable[M] = { 3,3,2 };

    //系统中N个进程中的每一个进程对M类资源的最大需求
    int iMax[N][M] = { {7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3} };

    //iNeed[N][M]每一个进程尚需的各类资源数
    //iAllocation[N][M]为系统中每一类资源当前已分配给每一进程的资源数
    int iNeed[N][M], iAllocation[N][M] = { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} };

    //进程名
    char cName[N] = { 'a','b','c','d','e' };

    bool bExitFlag = true;   //退出标记
    char ch;			     //接收选择是否继续提出申请时传进来的值

    bool bSafe;   //存放安全与否的标志
    //计算iNeed[N][M]的值
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            iNeed[i][j] = iMax[i][j] - iAllocation[i][j];

    output(iMax, iAllocation, iNeed, iAvailable, cName);
    bSafe = safety(iAllocation, iNeed, iAvailable, cName);

    if(bSafe)
    {

        cout<<"当前出于安全状态";
        cout<<"安全序列为:"<<endl;
        for(int i = 0;i < N;++i)
        {
            if(i == N-1)
                cout<<safeSeries[i];
            else
                cout<<safeSeries[i]<<"-->";
        }
        cout<<endl;
    }
    else
        cout<<"当前不是安全状态";

    //是否继续
    while (bExitFlag)
    {
        cout << "\n" << "继续提出申请?\ny为是;n为否。\n";
        cin >> ch;

        switch (ch)
        {
            case 'y':
                //cout<<"调用银行家算法";
                bSafe = banker(iAllocation, iNeed, iAvailable, cName);
                if (bSafe)   //安全,则输出变化后的数据
                    output(iMax, iAllocation, iNeed, iAvailable, cName);
                break;
            case 'n':
                cout << "退出\n";
                bExitFlag = false;
                break;
            default:
                cout << "输入有误,请重新输入:\n";
        }
    }
    return 0;
}

//输出
void output(int iMax[N][M],int iAllocation[N][M],int iNeed[N][M],int iAvailable[M],char cName[N])
{
    int i,j;

    cout<<"\n\t   Max  \tAllocation\t  Need  \t Available"<<endl;
    cout<<"\tA   B   C\tA   B   C\tA   B   C\t A   B   C"<<endl;

    for(i=0;i<N;i++)
    {
        cout<<cName[i]<<"\t";

        for(j=0;j<M;j++)
            cout<<iMax[i][j]<<"   ";
        cout<<"\t";

        for(j=0;j<M;j++)
            cout<<iAllocation[i][j]<<"   ";
        cout<<"\t";

        for(j=0;j<M;j++)
            cout<<iNeed[i][j]<<"   ";
        cout<<"\t";
        cout<<" ";

        //Available只需要输出一次
        if (i==0)
            for(j=0;j<M;j++)
                cout<<iAvailable[j]<<"   ";

        cout<<endl;
    }
}


//安全性算法,进行安全性检查
bool safety(int iAllocation[N][M], int iNeed[N][M], const int iAvailable[M],const char cName[N])
{
    // 工作向量Work表示系统目前可提供的资源,含有M个元素,安全性算法开始时Work等于iAvailable
    int Work[M];
    for (int i = 0; i < M; ++i) Work[i] = iAvailable[i];
    // 表示第i个进程是否已经分配资源,初始时全为false
    bool Finish[N];
    for (auto & finish : Finish) finish = false;
    // safeFlag:是否有安全序列的标记  fitProFlag: 是否为合适进程的标记
    bool safeFlag = true, fitProFlag = true;
    int index,i;
    for(index = 0;index < N; ++index)
    {
        for(i = 0;i < N;++i)
        {
            // 查找符合条件的进程(没有分配资源,且目前对各类资源的需求均不大于目前能提供的资源)
            if(Finish[i]) continue;     // 进程i已经可以分配过资源,就跳过
            fitProFlag = true;          // 将符合要求的进程标志标记为true
            for(int j = 0;j < M;++j)
            {
                if(iNeed[i][j] > Work[j])
                {
                    fitProFlag = false;         // 出现进程i目前对某一类资源的需求大于目前能提供的资源则将标志记为false,表示进程i不是符合要求的进程,跳出
                    break;
                }
            }
            // 当进程i为合适的进程时才执行
            if(fitProFlag)
            {
                safeSeries[index] = cName[i];       // 讲进程填入安全序列
                Finish[i] = true;                   // 标记能够为其分配到资源
                for(int k = 0;k<M;++k)              // 为进程i分配资源后,进程i执行结束,将以前进程i占用的资源回收
                    Work[k] += iAllocation[i][k];
                break;                              // 结束内层循环,进行下一轮的从前往后的查找
            }
        }
        if(i == N)
            safeFlag = false;
    }
    return safeFlag;
}

bool banker(int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N])
{
    // 1.信息的输入
    int proIndex;      // 申请资源的进程索引
    char proName;      // 申请资源的进程名称
    int request[M];    // proName申请资源的信息
    bool flag = true;  // 用于检测申请的资源数量是否符合要求
    cout<<"输入申请资源的进程:"<<endl;
    cin>>proName;
    for(int i = 0;i< N;++i)      // 查找输入的进程名字对应的下标
    {
        if(cName[i]==proName)
        {
            proIndex = i;
            break;
        }
    }
    cout<<"输入进程对各类资源申请的数量:"<<endl;
    for(int & re : request)
    {
        cin>>re;
    }
    // 2.检测申请的资源数量是否超过现在需要的资源数量
    for(int j = 0; j < M ; ++j)
    {
        if(request[j] > iNeed[proIndex][j])
        {
            flag = false;
            break;
        }
    }
    if(!flag)
    {
        cout<<"资源申请失败,该进程申请的资源超过需要的资源数量"<<endl;
        return false;
    }
    // 3.检测申请的资源数量是否超过现在能够提供的资源
    flag = true;      // flag为true表示有足够资源,为false表示申请的资源数量熬过
    for(int j = 0 ; j < M ; ++j)
    {
        if(request[j] > iAvailable[j])
        {
            flag = false;
            break;
        }
    }
    if(!flag) {
        cout << "资源申请失败,该进程申请的资源数量超过当前系统能提供的资源" << endl;
        return false;
    }
    // 4.假定分配资源,得到新的状态
    for(int j = 0;j < M;++j)
    {
        iAvailable[j] -= request[j];                // 系统可提供资源更新
        iAllocation[proIndex][j] += request[j];     // 已分配资源矩阵更新
        iNeed[proIndex][j] -= request[j];           // 更新proName进程还需要的资源
    }
    // 5.调用安全性算法,检测假定分配后是否存在安全序列。如果存在就提交并打印安全序列,不存在就回滚并给出说明
    if(safety(iAllocation,iNeed,iAvailable,cName))
    {
        cout<<"资源分配成功,安全序列为:"<<endl;
        for(int i = 0;i < N;++i)
        {
            if(i == N-1)
                cout<<safeSeries[i];
            else
                cout<<safeSeries[i]<<"-->";
        }
        cout<<endl;
        // 当某个进程提出申请资源后,该进程的最大的资源需求量iMax[i][0……M]等于已经分配的资源量iAllocation[i][0……M],即该进程当前对各类资源的需求量iNeed[i][0……M]均为0,
        // 进程执行结束。将该进程占用的资源回收。即修改当前系统可提供的资源iAvailable[0……M]增加上回收的该进程原先占用的资源iAllocation[0……M]。原先分配给该进程的资源iAllocation[0……M]置为0
        for(int i = 0;i < N;++i)
        {
            int j;
            for(j = 0;j < M;++j)
            {
                if(iNeed[i][j] != 0)
                    break;
            }
            if(j == M)
            {
                for(j = 0;j < M;++j)
                {
                    iAvailable[j] += iAllocation[i][j];
                    iAllocation[i][j] = 0;
                }
            }
        }
    }
    else
    {
        cout<<"资源分配失败"<<endl;
        for(int j = 0;j < M;++j)
        {
            iAvailable[j] += request[j];                // 系统可提供资源回滚
            iAllocation[proIndex][j] -= request[j];     // 已分配资源矩阵回滚
            iNeed[proIndex][j] += request[j];           // 回滚proName进程还需要的资源
        }
    }
    return true;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值