操作系统 银行家算法(C++)

理解

在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。

在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <time.h>
using namespace std;
const int maxn = 1e3 + 10;  ///进程、资源的最大数目

int n, m;       ///进程数n 资源种类m
int source[maxn];   ///各资源的数量
int tem_source[maxn];

bool is_use[maxn];   ///标记进程是否已经运行
bool tem_use[maxn];

struct node{
    int have;   ///已经拥有多少
    int maxi;   ///一共需要多少
    int need;   ///还需要多少
}program[maxn][maxn];

bool check_use(){
    for(int i = 1; i <= n; i++){
        if(!tem_use[i]){
            return false;
        }
    }
    return true;
}

bool check_safe(){
    for(int i = 1; i <= m; i++){
        tem_source[i] = source[i];
        tem_use[i] = is_use[i];
    }
    cout << "安全序列:";
    while(1){
        bool flag = false;      ///用于标记是否有进程被调用
        for(int i = 1; i <= n; i++){
            if(tem_use[i])   continue;

            bool enough = true;     ///标记剩余的资源是否足够给该进程使用
            for(int j = 1; j <= m; j++){
                if(program[i][j].need > tem_source[j]){
                    enough = false;
                    break;
                }
            }
            if(enough){///资源充足,可以分配
                /*因为系统无法知道什么时候一个过程将终止,或者之后它需要多少资源
                所以系统假定所有进程将最终试图获取其声明的最大资源并在不久之后终止。
                在大多数情况下,这是一个合理的假设*/
                flag = true;
                for(int j = 1; j <= m; j++){///分配需要的资源
                    tem_source[j] -= program[i][j].need;
                }
                for(int j = 1; j <= m; j++){///进程执行完毕后,回收资源
                    tem_source[j] += program[i][j].maxi;
                }
                tem_use[i] = true;///该进程已经被执行过
                cout << i << " ";
            }
        }
        if(!flag){///某次遍历没有执行进程
            if(check_use()){///检测是否还有进程没有执行过
                cout << "SUCCESS 安全" << endl;
                return true;
            }else{
                cout << "ERROR 不安全" << endl;
                return false;
            }
        }
    }
    exit(-1);
}

void init(){
    memset(is_use, false, sizeof(is_use));
    cout << "请输入进程个数、资源种类个数:";
    cin >> n >> m;

    cout << "请输入每种资源的数量:";
    for(int i = 1; i <= m; i++){
        cin >> source[i];
    }

    cout << "请输入每个进程对应的各类资源的需求量:";
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            cin >> program[i][j].maxi;
        }
    }

    cout << "请输入每个进程对应的各类资源的已分配量:";
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            cin >> program[i][j].have;
            program[i][j].need = program[i][j].maxi - program[i][j].have;
        }
    }
}

bool run_it(){
    int id, num[maxn];
    cin >> id;
    for(int i = 1; i <= m; i++){
        cin >> num[i];
    }
    bool flag = true, flag2 = true;
    for(int i = 1; i <= m; i++){
        if(num[i] > program[id][i].need){
            flag = false;
            break;
        }
        if(num[i] > source[i]){
            flag2 = false;
            break;
        }
    }
    if(!flag){
        cout << "申请后占有的资源超过了进程所能拥有的最大限度!" << endl;
    }else{
        if(!flag2){
            cout << "申请的资源数超过了目前剩余的资源数!" << endl;
        }
        else{
            bool flag3 = true;
            for(int i = 1; i <= m; i++){
                program[id][i].need -= num[i];
                program[id][i].have += num[i];
                source[i] -= num[i];
                if(program[id][i].need > 0){
                    flag3 = false;
                }
            }
            if(flag3)
                is_use[id] = true;
        }
    }
    if(!check_safe()){
        return false;
    }else{
        return true;
    }
}

int main(){
    init();
    if(!check_safe()){///检测最理想的情况下,是否会死锁
        exit(-1);
    }
    while(1){
        cout << "请输入任务的序号、要申请的各类资源数目:";
        if(!run_it()){
            break;
        }
    }
    return 0;
}

知识点参考

链接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章