操作系统 银行家算法 安全性检查

算法描述

银行家算法

设进程I提出请求Request[N],则银行家算法按如下规则进行判断

  1. 如果Request[N]<= Need [I, N],则转(2);否则,出错
  2. 如果Request[N]<= Available,则转(3);否则,出错
  3. 系统试探分配资源,修改相关数据:
  • Available = Available -Request
  • Allocation = Allocation +Request
  • Need= Need - Request
  1. 系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待
安全性检查
  1. 设置两个工作向量Work= Available;Finish[M]=False
  2. 从进程集合中找到一个满足下述条件的进程
    Finish[i]=False
    Need <=Work

如找到,执行(3);否则,执行(4)

  1. 设进程获得资源,可顺利执行,直至完成,从而释放资源
    Work=Work+ Allocation
    Finish=True
    Go To 2
  2. 如所有的进程Finish[M]=true,则表示安全;否则系统不安全

数据结构

int const RESOURCE_NUM = 20; // 最大资源的数目
int const PCB_COUNT = 10;    // 进程的数目
// 输入的进程
int M; //总进程数
int N; //资源种类
// 文件输出
ofstream fout;

char Name[RESOURCE_NUM];                 // 资源的名字
int PCBName[PCB_COUNT];                  // 进程的名字
int All_Resource[RESOURCE_NUM];          // 各种资源的数目总和
int Max[PCB_COUNT][RESOURCE_NUM];        // M个进程对N类资源最大资源需求量
int Available[RESOURCE_NUM];             // 系统可用资源数
int Allocation[PCB_COUNT][RESOURCE_NUM]; // M个进程已经得到N类资源的资源量
int Need[PCB_COUNT][RESOURCE_NUM];       // M个进程还需要N类资源的资源量
int Request[RESOURCE_NUM];               // 请求资源个数
int Work[RESOURCE_NUM] = {0};            // 系统可提供的资源数量
int Finish[RESOURCE_NUM] = {0};          // 完成的标志
int Security[PCB_COUNT];                 // 完成序列

//=========函数声明================
void initData();              // 输入信息
void showData();              // 展示输入的数据
bool safeAlgo();              // 安全序列函数
void allocationTest(int i);   // 对第i个进程分配预分配资源
void reAllocationTest(int i); // 对第 i 个进程回收预分配的资源
bool requestAlgo();           // 第 i 个进程请求资源
  • 获取系统的时间作为输出文件的名字
string getFileName(string algoName)
{
    // 获取时间 time_t是一个64位的整型。记录的是从1970-01-01 00:00:00到现在经过的时间,精度只能到秒
    time_t now = time(NULL);
    tm *t = localtime(&now);

    // 将信息输出到字符串流
    stringstream ss; // 引入sstream头文件
    ss << algoName << "LogFile" << t->tm_year + 1900 << "." << t->tm_mon + 1 << "." << t->tm_mday << ".." << t->tm_hour << "." << t->tm_min << "." << t->tm_sec << ".txt";
    cout << "写入的文件为: " << ss.str() << endl;
    return ss.str();
}
  • 输入资源信息、Max矩阵、Allocation矩阵
void initData()
{
    // 输入系统资源的种类与名字 名字用char类型
    cout << "输入系统资源的种类: " << endl;
    fout << "输入系统资源的种类: " << endl;

    cin >> N; // 资源的种类
    fout << N << endl;

    for (int i = 0; i < N; ++i)
    {
        cout << "资源的名字: " << endl;
        fout << "资源的名字: " << endl;

        cin >> Name[i];
        fout << Name[i] << endl;

        cout << "输入资源 " << Name[i] << " 的总个数 : " << endl;
        fout << "输入资源 " << Name[i] << " 的总个数 : " << endl;

        cin >> Available[i];
        fout << Available[i] << endl;
    }

    cout << "输入系统进程的数目:" << endl;
    fout << "输入系统进程的数目:" << endl;

    cin >> M; // M 进程的数目
    fout << M << endl;

    // 循环输入最大需求矩阵
    cout << "输入进程的最大需求矩阵" << endl;
    fout << "输入进程的最大需求矩阵" << endl;

    // 循环标志
    bool flag;

    // 每次输入是初始化输入为false
    flag = false;
    for (int i = 0; i < M; ++i)
    {
        cout << "第 " << i + 1 << " 个进程的Max矩阵" << endl;
        fout << "第 " << i + 1 << " 个进程的Max矩阵" << endl;

        PCBName[i] = i + 1;
        do
        {
            flag = false;
            for (int j = 0; j < N; ++j)
            {
                cin >> Max[i][j];
                fout << Max[i][j] << " ";
                // 输入检测,如果输入不合法,即需求的数目大于可分配的数目,重新输入所有的资源数目
                if (Max[i][j] > Available[j])
                {
                    flag = true;
                }
            }
            fout << endl;
            if (flag){
                cout << "输入需求的最大资源数不合法!请重新输入" << endl;
                fout << "输入需求的最大资源数不合法!请重新输入" << endl;
                cout << "第 " << i + 1 << " 个进程的Max矩阵" << endl;
                fout << "第 " << i + 1 << " 个进程的Max矩阵" << endl;
            }
            
        } while (flag);

    }

    // 初始化数据
    flag = false;
    /**
    * 输入分配的资源, 需要的资源为Need[i][j] = Max[i][j] - Allocation[i][j] 
    */
    for (int i = 0; i < M; ++i)
    {
        cout << "第 " << i + 1 << " 个进程的Allocation矩阵" << endl;
        fout << "第 " << i + 1 << " 个进程的Allocation矩阵" << endl;

        do
        {
            flag = false;
            for (int j = 0; j < N; ++j)
            {
                cin >> Allocation[i][j];
                fout << Allocation[i][j] << " ";

                if (Allocation[i][j] > Max[i][j])
                {   
                    flag = true;
                } else {
                    // 修改Need数组,得到还需分配的资源
                    Need[i][j] = Max[i][j] - Allocation[i][j];
                    // 修改Available数组, 得到系统剩余的资源
                     Available[j] -= Allocation[i][j];
                }
                
            }
            fout << endl;
            if (flag)
            {
                cout << "输入的Allocation大于Max!请重新输入" << endl;
                fout << "输入的Allocation大于Max!请重新输入" << endl;
                cout << "第 " << i + 1 << " 个进程的Allocation矩阵" << endl;
                fout << "第 " << i + 1 << " 个进程的Allocation矩阵" << endl;
            }
        } while (flag);
    }
}
  • 展示输入的信息
void showData()
{
    cout << "==========================================" << endl
         << endl;
    fout << "==========================================" << endl
         << endl;

    cout << "系统可用资源的数目: Avaliable: " << endl;
    fout << "系统可用资源的数目: Avaliable: " << endl;

    for (int i = 0; i < N; ++i)
    {
        cout << "   " << Name[i];
        fout << "   " << Name[i];
    }
    cout << endl;
    fout << endl;

    for (int i = 0; i < N; ++i)
    {
        cout << "   " << Available[i];
        fout << "   " << Available[i];
    }
    cout << endl;
    fout << endl;

    cout << "各个进程得到资源的情况: " << endl
         << "PCBName      Max      Allocation      Need" << endl;
    fout << "各个进程得到资源的情况: " << endl
         << "PCBName      Max      Allocation      Need" << endl;
    cout << "            ";
    fout << "            ";

    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            cout << Name[j] << " ";
            fout << Name[j] << " ";
        }
        cout << "       ";
        fout << "       ";
    }
    cout << endl;
    fout << endl;

    for (int i = 0; i < M; ++i)
    {
        cout << PCBName[i] << "           ";
        fout << PCBName[i] << "           ";

        // 输出max
        for (int j = 0; j < N; ++j)
        {
            cout << Max[i][j] << " ";
            fout << Max[i][j] << " ";
        }
        cout << "       ";
        fout << "       ";

        // 输出Allocation
        for (int j = 0; j < N; ++j)
        {
            cout << Allocation[i][j] << " ";
            fout << Allocation[i][j] << " ";
        }
        cout << "       ";
        fout << "       ";

        // 输出Need
        for (int j = 0; j < N; ++j)
        {
            cout << Need[i][j] << " ";
            fout << Need[i][j] << " ";
        }
        cout << endl;
        fout << endl;
    }
}

安全性算法

bool safeAlgo()
{
    /**
     * @brief 
     * 安全性算法执行
     * 首先work赋值为Available, Finish全部赋值为false
     * 假设全部都分配给Need, 分配之后进行检测
     * 1. 每一次检测都从第一个开始,如果每一个Need可以被分配,则进行分配
     * 2. 分配完成之后,从第一个循环开始
     */
    // 初始化 work
    int securityCNT = 0;
    for (int i = 0; i < N; ++i)
    {
        Work[i] = Available[i];
    }
    // 初始化Finish
    for (int i = 0; i < M; ++i)
    {
        Finish[i] = false; // 开始的时候假设都没有完成
    }
    // 安全序列算法
    int resource = 0;
    for (int i = 0; i < M; i++)
    {
        // 每一次检测都初始化为0
        resource = 0;
        // 对资源分配进行检测
        for (int j = 0; j < N; ++j)
        {
            // 如果进程没有完成, 并且可以得到需要
            if (Finish[i] == false && Need[i][j] <= Work[j])
            {
                resource++;

                // 各种资源都可以得到满足的时候
                if (resource == N)
                {

                    // work资源改变
                    for (int k = 0; k < N; ++k)
                    {
                        // 占用资源释放,相当于 work[k] += Need[i][k] + Allocation[i][k]; Need未进行计算
                        Work[k] += Allocation[i][k];
                    }
                    // 完成标志
                    Finish[i] = true;
                    // 添加到完成序列
                    Security[securityCNT++] = PCBName[i]; // 进程号

                    i = -1; // ++i 后从0开始
                }
            }
        }
    }

    // 检测全部的Finish 如果有一个未false 则为不安全序列
    for (int i = 0; i < M; ++i)
    {
        if (Finish[i] == false)
        {
            cout << "系统处于不安全序列" << endl;
            fout << "系统处于不安全序列" << endl;
            return false;
        }
    }

    // 此时存在安全序列
    cout << "此时系统是安全的: ";
    fout << "此时系统是安全的: ";

    for (int i = 0; i < M; ++i)
    {
        if (i == M - 1)
        {
            cout << Security[i] << endl;
            fout << Security[i] << endl;
        }
        else
        {
            cout << Security[i] << " -> ";
            fout << Security[i] << " -> ";
        }
    }
    return true;
}

银行家算法


// 预分配
void allocationTest(int i)
{
    /**
     * @brief 
     * Available减少
     * allocation增加
     * Need改变
     */
    for (int j = 0; j < N; ++j)
    {
        Available[j] -= Request[j];
        Allocation[i][j] += Request[j]; // 占用资源增加
        Need[i][j] -= Request[j];       // 需要的资源减少
    }
}

// 预分配失败,返回
void reAllocationTest(int i)
{
    for (int j = 0; j < N; ++j)
    {
        Available[j] += Request[j];
        Allocation[i][j] -= Request[j];
        Need[i][j] += Request[j];
    }
}

bool requestAlgo()
{
    cout << "输入要分配资源的进程:  " << endl;
    fout << "输入要分配资源的进程:  " << endl;

    int P;
    cin >> P;
    fout << P << endl;
    P -= 1; // 转换为下标
    cout << "输入要分配各个资源的数目" << endl;
    fout << "输入要分配各个资源的数目" << endl;

    for (int i = 0; i < N; ++i)
    {
        cout << Name[i] << ": ";
        fout << Name[i] << ": ";

        cin >> Request[i];
        fout << Request[i];
    }

    // 对输入的资源进行检测
    for (int i = 0; i < N; ++i)
    {
        // 检测是否大于还需要的进程
        if (Request[i] > Need[P][i])
        {
            cout << "资源申请大于 Need" << endl;
            fout << "资源申请大于 Need" << endl;

            return false;
        }
        else
        {
            // 检测是否有可用的资源
            if (Request[i] > Available[i])
            {
                cout << "申请资源大于 Avaliable" << endl;
                fout << "申请资源大于 Avaliable" << endl;

                return false;
            }
        }
    }

    // 合法 检测通过
    allocationTest(P); // 预分配资源
    showData();
    if (!safeAlgo())
    {
        // 没有安全序列
        reAllocationTest(P);
        showData();
        return false;
    }
    else
    {
        reAllocationTest(P);
        showData();
        return true;
    }
}

主函数

int main()
{
	// 得到文件名
    string fileName = getFileName("BankAlgo");
    // 打开文件
    fout.open(fileName.c_str());
    initData();
    showData();
    if (!safeAlgo())
    {
        return -1;
    }
    while (1)
    {
        requestAlgo();
        cout << "\t\tCtrl + C 结束进程" << endl
             << endl;
    }
    return 0;
}

测试用例

3
A
10
B
5
C
7

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

0 1 0
3 0 2
3 0 2
2 1 1
0 0 2
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值