實驗二、銀行家算法


(一)    目的和要求

銀行家算法是由Dijkstra設計的最具有代表性的避免死鎖的算法。本實驗要求用高級語言編寫一個銀行家的模擬算法。通過本實驗可以對預防死鎖和銀行家算法有更深刻的認識。

(二)    實驗內容

1、  設置數據結構

包括可利用資源向量(Availiable),最大需求矩陣(Max),分配矩陣(Allocation),需求矩陣(Need)

2、  設計安全性算法

設置工作向量Work 表示系統可提供進程繼續運行可利用資源數目,Finish 表示系統是否有足夠的資源分配給進程

 

/* Note:Your choice is C IDE */
/* Note:Your choice is C IDE */
#include "stdio.h"

#include <iostream>
using namespace std;

/*子函數聲明*/
int Isprocessallover();                //判斷系統中的進程是否全部運行完畢
void Systemstatus();                   //顯示當前系統中的資源及進程情況
int Banker(int, int *);                //銀行家算法
void Allow(int, int *);                //若進程申請不導致死鎖,用此函數分配資源
void Forbidenseason(int);             //若發生死鎖,則顯示原因

/*全局變量*/
int Availiable[3] = { 3, 3, 2 };              //初始狀態,系統可用資源量                         
int Max[5][3] = { { 7, 5, 3 }, { 3, 2, 2 }, { 9, 0, 2 }, { 2, 2, 2 }, { 4, 3, 3 } };
//各進程對各資源的最大需求量
int Allocation[5][3] = { { 0, 1, 0 }, { 2, 0, 0 }, { 3, 0, 2 }, { 2, 1, 1 }, { 0, 0, 2 } };
//初始狀態,各進程占有資源量
int Need[5][3] = { { 7, 4, 3 }, { 1, 2, 2 }, { 6, 0, 0 }, { 0, 1, 1 }, { 4, 3, 1 } };
//初始狀態時,各進程運行完畢,還需要的資源量 
int over[5] = { 0, 0, 0, 0, 0 };               //標記對應進程是否得到所有資源並運行完畢  
int g_pAllAvailiable[3]={10,5,6};                //系統資源總數

/*主函數*/
void main()
{
    int process = 0;                           //發出請求的進程
    int decide = 0;                            //銀行家算法的返回值
    int Request[3] = { 0, 0, 0 };              //申請的資源量數組
    int sourcenum = 0;                         //申請的各資源量
    /*判斷系統中進程是否全部運行完畢*/
step1:  
          if (Isprocessallover() == 1)
        {
              cout << "系統中全部進程運行完畢!";
              return;
        }
          /*顯示系統當前狀態*/
          Systemstatus();
          /*人機交互界面*/
step2: 
           cout << "\n輸入發出請求的進程(輸入 “0”退出系統): ";
          cin >> process;
          if (process == 0)
          {
              cout << "放棄申請,退出系統!";
              return;
          }
          if (process<1 || process>5 || over[process - 1] == 1)
          {
              cout << "系統無此進程!\n";
              goto step2;
          }
          cout << "此進程申請各資源(A,B,C)數目:\n";
          for (int h = 0; h < 3; h++)
          {
              cout << char(65 + h) << "資源:";
              cin >> sourcenum;
              Request[h] = sourcenum;
          }
          /*用銀行家算法判斷是否能夠進行分配*/
          decide = Banker(process, Request);
          if (decide == 0)
          {
              /*將此進程申請資源分配給它*/
              Allow(process, Request);
              goto step1;
          }
          else
          {
              /*不能分配,顯示原因*/
              Forbidenseason(decide);
              goto step2;
          }

}

/*子函數Isprocessallover( )的實現*/
int Isprocessallover()
{
    int processnum = 0;
    for (int i = 0; i < 5; i++)
    {
        /*判斷每個進程是否運行完畢*/
        if (over[i] == 1)
            processnum++;
    }
    if (processnum == 5)
        /*系統中全部進程運行完畢*/
        return 1;
    else
        return 0;
}

/*子函數Systemstatus( )的實現*/
void Systemstatus()
{
    cout << "此刻系統中存在的進程:\n";
    for (int i = 0; i < 5; i++)
    {
        if (over[i] != 1)
            cout << "P" << i + 1 << "  ";
    }
    cout << endl;
    cout << "此刻系統可利用資源(單位:個):\n";
    cout << "A  B  C\n";
    for (int a = 0; a < 3; a++)
    {
        cout << Availiable[a] << "  ";
    }
    cout << endl;
    cout << "此刻各進程已占有資源如下(單位:個): \n"
        << "    A  B  C\n";
    for (int b = 0; b < 5; b++)
    {
        if (over[b] == 1)
            continue;
        cout << "P" << b + 1 << "  ";
        for (int c = 0; c < 3; c++)
            cout << Allocation[b][c] << "  ";
        cout << endl;
    }
    cout << "各進程運行完畢還需各資源如下(單位:個):\n"
        << "    A  B  C\n";
    for (int f = 0; f < 5; f++)
    {
        if (over[f] == 1)
            continue;
        cout << "P" << f + 1 << "  ";
        for (int g = 0; g < 3; g++)
            cout << Need[f][g] << "  ";
        cout << endl;
    }
}

/*子函數Banker(int ,int &)的實現*/
int Banker(int p, int *R)
{
    int num = 0;                            //標記各資源是否能滿足各進程需要
    int Finish[5] = { 0, 0, 0, 0, 0 };                //標記各進程是否安全運行完畢
    int work[5] = { 0, 0, 0, 0, 0 };                 //用於安全檢查
    int AvailiableTest[3];                   //用於試分配  
    int AllocationTest[5][3];                //同上
    int NeedTest[5][3];                    //同上
    
    /*判斷申請的資源是否大於系統可提供的資源總量*/
    for(int n=0;n<3;++n)
    {
        if(R[n]>Availiable[n])
        {
            return 1;
        }
    }
    /*返回拒絕分配原因*/
    
    //需求遠大於系統總量
    for(int i=0;i<3;++i)
    {
        if(R[i]>g_pAllAvailiable[i])
        {
            cout<<"此需求永得不到滿足,請求不接受!"<<endl;
            return 1;
        }
    }
    
    
    /*判斷該進程申請資源量是否大於初始時其申明的需求量*/
    for(int j=0;j<3;++j)
    {
        if(R[j]>Need[p-1][j])
        {
            return  2;
        }
    }
            /*返回拒絕原因*/
            
    /*為檢查分配的各數據結構賦初值*/
    for (int t = 0; t < 3; t++)
    {
        AvailiableTest[t] = Availiable[t];
    }
    for (int u = 0; u < 5; u++)
    {
        for (int v = 0; v < 3; v++)
        {
            AllocationTest[u][v] = Allocation[u][v];
        }
    }
    for (int w = 0; w < 5; w++)
    {
        for (int x = 0; x < 3; x++)
        {
            NeedTest[w][x] = Need[w][x];
        }
    }
    /*進行試分配*/
    for (int k = 0; k < 3; k++)                                                                       //修改NeedTest[]
    {
        AvailiableTest[t] = AvailiableTest[t] - *(R + k);
        AllocationTest[p - 1][k] = AllocationTest[p - 1][k] + *(R + k);
        NeedTest[p - 1][k] = NeedTest[p - 1][k] - *(R + k);
    
    }
    /*檢測進程申請得到滿足后,系統是否處於安全狀態*/
    for (int l = 0; l < 3; l++)
    {
        work[l] = AvailiableTest[l];
    }
    for (int m = 1; m <= 5; m++)
    {
        for (int n = 0; n < 5; n++)
        {
            num = 0;
            /*尋找用此刻系統中沒有運行完的進程*/
            if (Finish[n] == 0 && over[n] != 1)
            {
                for (int p = 0; p < 3; p++)
                {
                    if (NeedTest[n][p] <= work[p])
                        num++;
                }
                if (num == 3)
                {
                    for (int q = 0; q < 3; q++)
                    {
                        work[q] = work[q] + AllocationTest[n][q];
                    }
                    Finish[n] = 1;
                }
            }
        }
    }
    for (int r = 0; r < 5; r++)
    {
        if (Finish[r] == 0 && over[r] != 1)
            /*返回拒絕分配原因*/
            return 3;
    }
    return 0;
}

/*子函數Allow(int ,int &)的實現*/
void Allow(int p, int *R)
{
    cout << "可以滿足申請!";
    static int overnum;
    /*對進程所需的資源進行分配*/
    for (int t = 0; t < 3; t++)
    {
        Availiable[t] = Availiable[t] - *(R + t);
        Allocation[p - 1][t] = Allocation[p - 1][t] + *(R + t);
        Need[p - 1][t] = Need[p - 1][t] - *(R + t);
    }
    /*分配后判斷其是否運行完畢*/
    overnum = 0;
    for (int v = 0; v < 3; v++)
    {
        if (Need[p - 1][v] == 0)
            overnum++;
    }
    if (overnum == 3)
    {
        /*此進程運行完畢,釋放其占有的全部資源*/
        for (int q = 0; q < 3; q++)
            Availiable[q] = Availiable[q] + Allocation[p - 1][q];
        /*標記該進程運行完畢*/
        over[p - 1] = 1;
        cout << "進程P" << p << "所需資源全部滿足,此進程運行完畢!\n";
    }
}

/*子函數Forbidenseason(int )的實現*/
void Forbidenseason(int d)
{
    cout << "不能滿足申請,此進程掛起,原因為:\n";
    switch (d)
    {
    case 1:cout << "申請的資源量大於系統可提供的資源量!"; break;
    case 2:cout << "申請的資源中有某種資源大於其聲明的需求量!"; break;
    case 3:cout << "若滿足申請,系統將進入不安全狀態,可能導致死鎖!";
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM