銀行家算法:解決多線程死鎖問題


死鎖:

死鎖產生的現場:當A進程P S2信號量而B進程P S1信號量時就會產生死鎖,因為S2信號量需要B進程釋放,而S1信號量需要A進程釋放,因此兩個進程都在等相互的資源,造成死鎖。

 死鎖產生的條件:

互斥條件:進程要求對所分配的資源進行排它性控制,即在一段時間內某資源僅為一進程所占用。(信號量s1 s2為互斥的信號量,只能被一個進程占用)

請求和保持條件:當進程因請求資源而阻塞時,對已獲得的資源保持不放。(A進程在獲取s2阻塞時,一直占用s1)

不可剝奪條件:進程已獲得的資源在未使用完之前,不能剝奪,只能在使用完時由自己釋放。(s1只能由A進程釋放,s2只能由B進程釋放)

環路等待條件:在發生死鎖時,必然存在一個進程--資源的環形鏈。(A B 進程都是環形鏈路)


避免死鎖的算法:

銀行家算法是避免死鎖的一種重要方法,防止死鎖的機構只能確保上述四個條件之一不出現,則系統就不會發生死鎖。通過這個算法可以用來解決生活中的實際問題,如銀行貸款等。

程序實現思路銀行家算法顧名思義是來源於銀行的借貸業務,一定數量的本金要應多個客戶的借貸周轉,為了防止銀行加資金無法周轉而倒閉,對每一筆貸款,必須 考察其是否能限期歸還。在操作系統中研究資源分配策略時也有類似問題,系統中有限的資源要供多個進程使用,必須保證得到的資源的進程能在有限的時間內歸還 資源,以供其他進程使用資源。如果資源分配不得到就會發生進程循環等待資源,則進程都無法繼續執行下去的死鎖現象。
把一個進程需要和已占有資源的情況記錄在進程控制中,假定進程控制塊PCB其中“狀態”有就緒態、等待態和完成態。當進程在處於等待態時,表示系統不能滿 足該進程當前的資源申請。“資源需求總量”表示進程在整個執行過程中總共要申請的資源量。顯然,,每個進程的資源需求總量不能超過系統擁有的資源總 數, 銀行算法進行資源分配可以避免死鎖.
 
一.程序流程圖:
1.初始化算法流程圖:
銀行家算法實現 - 如雪 - 丟了幸福的豬
2.銀行家算法流程圖:
銀行家算法實現 - 如雪 - 丟了幸福的豬
 3.安全性算法流程圖:
銀行家算法實現 - 如雪 - 丟了幸福的豬
二.銀行家算法設計:
1.設進程i提出請求Request[n],則銀行家算法按如下規則進行判斷。
(1)如果Request[n]>Need[i,n],則報錯返回。
(2)如果Request[n]>Available,則進程i進入等待資源狀態,返回。
(3)假設進程i的申請已獲批准,於是修改系統狀態:
    Available=Available-Request
    Allocation=Allocation+Request
    Need=Need-Request
(4)系統執行安全性檢查,如安全,則分配成立;否則試探險性分配作廢,系統恢復原狀,進程等待。
2.安全性檢查
(1)設置兩個工作向量Work=Available;Finish =False
(2)從進程集合中找到一個滿足下述條件的進程,
   Finish =False
   Need<=Work
   如找到,執行(3);否則,執行(4)
(3)設進程獲得資源,可順利執行,直至完成,從而釋放資源。
    Work=Work+Allocation
    Finish=True
    GO TO 2
(4)如所有的進程Finish =true,則表示安全;否則系統不安全。
3.數據結構
假設有M個進程N類資源,則有如下數據結構:
#define W 10
#define R 20
int A ;                      //總進程數
int B ;                     //資源種類
int ALL_RESOURCE[W];        //各種資源的數目總和
int MAX[W] ;             //M個進程對N類資源最大資源需求量
int AVAILABLE ;          //系統可用資源數
int ALLOCATION[W] ;      //M個進程已經得到N類資源的資源量
int NEED[W] ;            //M個進程還需要N類資源的資源量
int Request ;            //請求資源個數
5.4主要函數說明
void showdata();           //主要用來輸出資源分配情況
void changdata(int);       //主要用來輸出資源分配后后的情況
void rstordata(int);       //用來恢復資源分配情況,如:銀行家算法時,由於分配不安全則要恢復資源分配情況
int chkerr(int);           //銀行家分配算法的安全檢查
void bank()   ;             //銀行家算法
銀行家算法的課程設計(二)VC++6.02008-01-28 15:29源程序
數據結構分析:
假設有M個進程N類資源,則有如下數據結構:
#define W 10
#define R 20
int A ;                      //總進程數
int B ;                     //資源種類
int ALL_RESOURCE[W];        //各種資源的數目總和
int MAX[W] ;             //M個進程對N類資源最大資源需求量
int AVAILABLE ;          //系統可用資源數
int ALLOCATION[W] ;      //M個進程已經得到N類資源的資源量
int NEED[W] ;            //M個進程還需要N類資源的資源量
int Request ;            //請求資源個數
第3章   程序清單#include <iostream>
using namespace std;
#define MAXPROCESS 50                        /*最大進程數*/
#define MAXRESOURCE 100                        /*最大資源數*/
int AVAILABLE[MAXRESOURCE];                    /*可用資源數組*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩陣*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*分配矩陣*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩陣*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*進程需要資源數*/
bool FINISH[MAXPROCESS];                        /*系統是否有足夠的資源分配*/
int p[MAXPROCESS];                             /*記錄序列*/
int m,n;                                    /*m個進程,n個資源*/
void Init();
bool Safe();
void Bank();
int main()
{
    Init();
    Safe();
    Bank();
}
void Init()                /*初始化算法*/
{
    int i,j;
    cout<<"\t---------------------------------------------------"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                 銀行家算法                    ||"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                             計科04151  李宏   ||"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                                  0415084211   ||"<<endl;
    cout<<"\t---------------------------------------------------"<<endl;
    cout<<"請輸入進程的數目:";
    cin>>m;
    cout<<"請輸入資源的種類:";
    cin>>n;
    cout<<"請輸入每個進程最多所需的各資源數,按照"<<m<<"x"<<n<<"矩陣輸入"<<endl;
    for(i=0;i<m;i++)
    for(j=0;j<n;j++)
    cin>>MAX[j];
    cout<<"請輸入每個進程已分配的各資源數,也按照"<<m<<"x"<<n<<"矩陣輸入"<<endl;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>ALLOCATION[j];
            NEED[j]=MAX[j]-ALLOCATION[j];
            if(NEED[j]<0)
            {
                cout<<"您輸入的第"<<i+1<<"個進程所擁有的第"<<j+1<<"個資源數錯誤,請重新輸入:"<<endl;
                j--;
                continue;
            }
        }
    }
    cout<<"請輸入各個資源現有的數目:"<<endl;
    for(i=0;i<n;i++)
    {
        cin>>AVAILABLE;
    }
}
void Bank()                /*銀行家算法*/
{
    int i,cusneed;
    char again;
    while(1)
    {
        cout<<"請輸入要申請資源的進程號(注:第1個進程號為0,依次類推)"<<endl;
        cin>>cusneed;
        cout<<"請輸入進程所請求的各資源的數量"<<endl;
        for(i=0;i<n;i++)
        {
            cin>>REQUEST[cusneed];
        }
        for(i=0;i<n;i++)
        {
            if(REQUEST[cusneed]>NEED[cusneed])
            {
                cout<<"您輸入的請求數超過進程的需求量!請重新輸入!"<<endl;
                continue;
            }
            if(REQUEST[cusneed]>AVAILABLE)
            {
                cout<<"您輸入的請求數超過系統有的資源數!請重新輸入!"<<endl;
                continue;
            }
        }
        for(i=0;i<n;i++)
        {
            AVAILABLE-=REQUEST[cusneed];
            ALLOCATION[cusneed]+=REQUEST[cusneed];
            NEED[cusneed]-=REQUEST[cusneed];
        }
        if(Safe())
        {
            cout<<"同意分配請求!"<<endl;
        }
        else
        {
            cout<<"您的請求被拒絕!"<<endl;
            for(i=0;i<n;i++)
            {
                AVAILABLE+=REQUEST[cusneed];
                ALLOCATION[cusneed]-=REQUEST[cusneed];
                NEED[cusneed]+=REQUEST[cusneed];
            }
        }
        for(i=0;i<m;i++)
        {
            FINISH=false;
        }
        cout<<"您還想再次請求分配嗎?是請按y/Y,否請按其它鍵"<<endl;
        cin>>again;
        if(again=='y'||again=='Y')
        {
            continue;
        }
        break;
        }
}
bool Safe()                                    /*安全性算法*/
{
    int i,j,k,l=0;
    int Work[MAXRESOURCE];                    /*工作數組*/
    for(i=0;i<n;i++)
    Work=AVAILABLE;
    for(i=0;i<m;i++)
    {
        FINISH=false;
    }
    for(i=0;i<m;i++)
    {    
        if(FINISH==true)
        {
            continue;
        }
        else
        {
            for(j=0;j<n;j++)
            {
                if(NEED[j]>Work[j])
                {
                    break;
                }
            }
            if(j==n)
            { 
                FINISH=true;
                for(k=0;k<n;k++)
                {
                    Work[k]+=ALLOCATION[k];
                }
                p[l++]=i;
                i=-1;
            }
            else
            {
                continue; 
            }
        }
        if(l==m)
        {
            cout<<"系統是安全的"<<endl;
            cout<<"安全序列:"<<endl;
            for(i=0;i<l;i++)
            {
                cout<<p;
                if(i!=l-1)
                {
                    cout<<"-->";
                }
            }
            cout<<""<<endl;
            return true;
        }
    }
    cout<<"系統是不安全的"<<endl;
    return false;

輸出數據
銀行家算法實現 - 如雪 - 丟了幸福的豬
銀行家算法的模擬實現”是本學期操作系統課程唯一的課程設計。在設計此程序的過程中,我遇到過許多問題,也學到了很多東西。本程序的設計實現主要是用 C++語言實現,通過對程序算法的設計優化、輸出顯示的格式設計、輸入過程中的異常處理等一些設計過程中的問題的考慮解決,在C++學習上也有了很大的進 步。程序設計過程中開始遇到的最大的問題是算法的結構設計問題,課本上只給了設計要求及簡單的算法,要真正實現還需要考慮很多方面。在算法的數據結構設計 上考慮了很長時間。在程序設計中先后參考了很多網絡資料,也參考了一些別人寫的的程序,綜合這些算法思想和自己的思路對程序做了很好的設計方式,對一些算 法的優越性等也作了一些考慮。此外考慮最多的就是異常錯誤處理的設計。一個好的程序必須能在各種環境下都有其相應的處理方式,至少能應對一些常見的可能發 生的錯誤。比如一般的要求輸入為數字時,如果輸入了一個非數字字符,程序就會立即出錯無法繼續運行,本程序針對這個問題設計了一個shuzi();函數進 行處理,處理方式為:接受鍵盤輸入的字符為字符串,然后對字符串的每個字符進行判斷是否為數字,如果有非數字字符出現則提示出錯並要求重新輸入。又如在判 斷是否繼續時要求輸入Y/N時,按一般的方式,如果輸入為多個字符,則多余的字符會保存在緩沖區,到下次要求輸入時輸入而導致出錯,對此問題設計處理方式 為接受輸入字符保存為串然后只取其首字符進行判斷。還有很多類似的錯誤處理。還有在設置程序的顯示優化時,發現暫停函數在不同的情況下執行順序不同,如此 等等。在課程設計過程中遇到了許多問題,也向同宿舍的同學做了一些請教一起討論,也因此從他們身上學到了許多東西。


免責聲明!

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



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