1. 程式人生 > >銀行家演算法——死鎖避免(C++程式碼實現)

銀行家演算法——死鎖避免(C++程式碼實現)

安全狀態

如果存在一個安全序列,那麼系統處於安全狀態。對於程序順序<P1,P2,...,Pn>,有如下

            Pi-need <= Pj-hold + All-available

則這一順序為安全序列。可以保證所有程序按此順序執行後,資源分配不會發生死鎖。

銀行家演算法

·資料結構

1)可利用資源向量Available是個含有m個元素的陣列,其中的每一個元素代表一類可利用的資源數目。如果Available[j]=K,則表示系統中現有Rj類資源K個。2)最大需求矩陣Max這是一個n×m的矩陣,它定義了系統中n個程序中的每一個程序對m類資源的最大需求。如果Max[i,j]=K,則表示程序i需要Rj類資源的最大數目為K。3)分配矩陣Allocation這也是一個n×m的矩陣,它定義了系統中每一類資源當前已分配給每一程序的資源數。如果Allocation[i,j]=K,則表示程序i當前已分得Rj類資源的 數目為K。4)需求矩陣Need。這也是一個n×m的矩陣,用以表示每一個程序尚需的各類資源數。如果Need[i,j]=K,則表示程序i還需要Rj類資源K個,方能完成其任務。Need[i,j]=Max[i,j]-Allocation[i,j]
5)採用一些符號
設X,Y是長度為n的陣列,則X<=Y當且僅當對於所有i=1,2,3……n,X[i] <= Y[i]。

·安全性演算法

1)設定兩個長度為n的陣列,Work=Available,Finish[i]=False。2)從程序集合中找到一個滿足下述條件的程序,    Finish[i]==false;        Needi<=Work;    如找到,執行3);否則,執行4)3)設程序獲得資源,可順利執行,直至完成,從而釋放資源。    Work=Work+Allocation;    Finish[i]=true;    轉2)4)如所有的程序Finish= true,則表示安全;否則系統不安全。

·資源請求演算法

Request-i是程序Pi的請求向量,若Request-i[j] = k,則Pi需要資源型別j的例項k個。

1)若Request-i>Need-i,出錯,超過其最大請求。

2)若Request-i>Available,等待,當前無可用資源。

3)若當前資源可滿足,則試探性地為其分配資源:

    Available -= Request-i;

    Allocation += Request-i;

    Need-i -= Request-i;

    然後此時判斷安全性,若安全,交易成功,若不安全,狀態回退,Pi必須等待。

·程式碼實現

#include <iostream>

using namespace std;

const int source = 3;///資源型別數
const int progress = 5;///程序數

int availabe[source];///當前系統可用資源
int mmax[progress][source];///程序所需最大資源
int allocation[progress][source];///已經給程序分配的資源
int need[progress][source];///程序還需要的資源

int safeSeq[progress];///安全序列

bool isLess(int a[], int b[], int len){///判斷X<Y
    bool less = true;
    for(int i = 0; i < len; i++){
        if(a[i] > b[i]){
            less = false;
            break;
        }
    }

    return less;
}

bool isSafe(){///判斷安全狀態
    int work[source];
    bool finish[progress];
    bool safe = true;

    for(int i = 0; i < source; i++){
        work[i] = availabe[i];
    }

    for(int i = 0; i < progress; i++){
        finish[i] = false;
    }


    int finishCount = 0;
    int seqIndex = 0;
    while(finishCount < progress){
        bool flag = false;

        for(int i = 0; i < progress; i++){
            if(finish[i] == false && isLess(need[i], work, source)){
                finish[i] = true;
                finishCount++;
                for(int j = 0; j < source; j++){
                    work[j] += allocation[i][j];
                }

                safeSeq[seqIndex++] = i;
                flag = true;
            }
        }

        if(!flag){///找不到符合條件的i就退出
            safe = false;
            break;
        }
    }

    if(safe == true){
        cout << "safe!:";
        for(int i = 0; i < progress; i++){
            cout << safeSeq[i] << " ";
        }
        cout << endl;
    }
    else{
        cout << "not safe!" << endl;
    }

    return safe;
}

void init(){
    cout << "Input the instances of each source:\n";
    for(int i = 0; i < source; i++){
        cin >> availabe[i];
    }

    cout << "Input the max demands of each progress:\n";
    for(int i = 0; i < progress; i++){
        for(int j = 0; j < source; j++){
            cin >> mmax[i][j];
        }
    }

    cout << "Input the allocation of each progress:\n";
    for(int i = 0; i < progress; i++){
        for(int j = 0; j < source; j++){
            cin >> allocation[i][j];
        }
    }

    for(int i = 0; i < progress; i++){
        for(int j = 0; j < source; j++){
            need[i][j] = mmax[i][j] - allocation[i][j];
            availabe[j] -= allocation[i][j];
        }
    }
}

void request(){
    int pi;
    int piRequest[source];
    cout << "Input progress i and its request:\n";
    cin >> pi;
    for(int i = 0; i < source; i++){
        cin >> piRequest[i];
    }

    if(isSafe()){
        cout << "now is safe\n";
    }

    if(!isLess(piRequest, need[pi], source)){
        cout << "Error! max demands overflow.\n";
        return;
    }

    if(!isLess(piRequest, availabe, source)){
        cout << "Wait for available source.\n";
        return;
    }

    for(int i = 0; i < source; i++){///試探修改
        availabe[i] -= piRequest[i];
        allocation[pi][i] += piRequest[i];
        need[pi][i] -= piRequest[i];
    }
    if(isSafe()){
        cout << "Deal!\n";
    }
    else{///狀態回退
        for(int i = 0; i < source; i++){
            availabe[i] += piRequest[i];
            allocation[pi][i] -= piRequest[i];
            need[pi][i] += piRequest[i];
        }
    }
}

int main(){
    init();

    while(true){
        request();
    }

    return 0;
}

以上程式碼在code blocks17.02通過除錯

測試用例

初始化:

10 5 7
7 5 3 3 2 2 9 0 2 2 2 2 4 3 3
0 1 0 2 0 0 3 0 2 2 1 1 0 0 2

Request1=(1,0,2) -----》滿足;

Request4=(3,3,0)-------》沒這麼多資源可用

Request0=(0,2,0)----------》資源夠用但會導致不安全狀態