操作系統 銀行家算法(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;
}

知識點參考

鏈接

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