操作系統——銀行家算法(java實現)


1.數據結構

  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] 

2.銀行家算法

在避免死鎖的方法中,所施加的限制條件較弱,有可能獲得令人滿意的系統性能。在該方法中把系統的狀態分為安全狀態和不安全狀態,只要能使系統始終都處於安全狀態,便可以避免發生死鎖。銀行家算法的基本思想是分配資源之前,判斷系統是否是安全的;若是,才分配。它是最具有代表性的避免死鎖的算法。

設進程cusneed提出請求REQUEST [i],則銀行家算法按如下規則進行判斷。

(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],則轉(2);否則,出錯。

(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],則轉(3);否則,等待。

(3)系統試探分配資源,修改相關數據:

AVAILABLE[i]-=REQUEST[cusneed][i];

ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];

NEED[cusneed][i]-=REQUEST[cusneed][i];

(4)系統執行安全性檢查,如安全,則分配成立;否則試探險性分配作廢,系統恢復原狀,進程等待。

 

3.安全性算法 

(1)設置兩個工作向量Work=AVAILABLE;FINISH

(2)從進程集合中找到一個滿足下述條件的進程,

FINISH==false;

NEED<=Work;

如找到,執行(3);否則,執行(4)

(3)設進程獲得資源,可順利執行,直至完成,從而釋放資源。

Work=Work+ALLOCATION;

Finish=true;

GOTO 2

(4)如所有的進程Finish= true,則表示安全;否則系統不安全。

 

主要代碼:

安全性檢測:

public void allocation(){
        flag_i.clear();
        for (int i = 0; i < this.processes_Size ; i++) {
            Finish[i] = false;
        }
        for (int i = 0; i < this.Resources_Size ; i++) {
            Work[0][i] = AvailableTmp[0][i];
        }
        int count = 0;
        int flag = 0; //flag_i中的個數
        while (count < this.processes_Size){
            for (int i = 0; i < this.processes_Size ; i++) {
                if(flag_i.contains(i)){
                    continue;
                }else {
                    int k = 0;
                    while (k < this.Resources_Size){
                        if(NeedTmp[i][k] <= Work[count][k] && (this.Finish[count]==false)){
                            k++;
                        }else {
                            k = this.Resources_Size+1;
                        }
                    }
                    if(k == this.Resources_Size){
                        flag_i.add(i);
                        flag++;
                        break;   //每次添加一個
                    }
                }
            }

            //
            //每走一遍for循環應該找到一個,才能往下執行
            if((count+1) == flag){
                for (int i = 0; i < this.Resources_Size; i++) {
                    Work_All[count][i] = Work[count][i] + AllocationTmp[(int) flag_i.get(count)][i];
                }
                this.Finish[count] = true;
                count++;
                //賦值
                for (int i = 0; i < this.Resources_Size; i++) {
                    Work[count][i] = Work_All[count - 1][i];
                }
            }
            else {
                count++;
                System.out.println("第"+count+"次安全性檢測失敗!");
                break;
            }
            if(Finish[count-1] == false){
                break;
            }
        }
        //跳出循環如果有進程數個值,說明每個進程都能滿足,將試分配的值真實分配
        if(flag_i.size() == this.processes_Size){
            for (int i = 0; i < this.processes_Size; i++) {
                for (int j = 0; j < this.Resources_Size ; j++) {
                    Allocation[i][j] =AllocationTmp[i][j];
                    Need[i][j] = NeedTmp[i][j];
                }
            }
            for (int i = 0; i < this.Resources_Size; i++) {
                Available[0][i] = AvailableTmp[0][i];
            }
            showResult();
            System.out.println("*********************************");
            show();
        }else {
            if(flag_i.size() == 0){
                System.out.println("不滿足任何進程的需求!");
                System.out.println("無安全序列!");
                System.out.println("******************************");
                show();
            }else {
                System.out.println("無安全序列!");
                System.out.println("*****************************");
                show();
            }

        }

    }

 

銀行家分配部分:

 private void requset() {
        copy();
        System.out.println("請輸入要請求資源的進程號:");
        String name = scanner.next();
        int putInto = -1;    //判斷輸入的是幾號進程
        for (int i = 0; i < this.processes_Size; i++) {
            if (name.equals(processes[i])){
                putInto = i;
            }
        }
        //如果輸入的在進程序列內不存在
        if(putInto == -1){
            System.out.println("非法輸入!");
            return;
        }
        System.out.println();
        System.out.println("請輸入再次申請的資源大小:");
        int[] num = new int[this.Resources_Size];   //輸入的request值
        for (int i = 0; i < this.Resources_Size; i++) {
            num[i] = scanner.nextInt();
        }
        int k = 0;
        for (int i = 0; i < this.Resources_Size; i++) {
            if ((num[i] <= Need[putInto][i]) && (num[i] <= Available[0][i])) {
                k++;
            } else {
                if((num[i] > Need[putInto][i])) {
                    System.out.println("申請大於需要的進程!");
                    System.out.println("***************************");
                    show();
                    return;
                }
                if(num[i] > Available[0][i]){
                    System.out.println("資源不足!");
                    System.out.println("***************************");
                    show();
                    return;
                }

            }

        }
        //跳出說明滿足要求嘗試分配資源
        if(k == this.Resources_Size){
            for (int j = 0; j < this.Resources_Size; j++) {
                NeedTmp[putInto][j] = NeedTmp[putInto][j] - num[j];
                AllocationTmp[putInto][j]  = AllocationTmp[putInto][j] + num[j];
                AvailableTmp[0][j] = AvailableTmp[0][j] - num[j];
            }

        }
              allocation();
    }

         但是遇到的問題是,當滿足銀行家算法但是不滿足安全性算法時,怎么將銀行家預分配的再次還給初始分配前的值,最終采用臨時的副本數組,每次安全性算法都是對副本操作,當滿足時,才將原數組改變,然后將其輸出,當然還有當一個就是一個進程的所需要的資源已經全部得到,此時應該將其刪除序列表,並且將其拿到的資源全部還給系統,以便於其他進程的申請。

 

刪除進程(已經獲取到了全部所需要的資源):

 private void resReturn(){
        int count = 0;
        int num = 0;
        while (count < processes_Size) {
            for (int i = 0; i < this.Resources_Size; i++) {
                if (Need[count][i] == 0){
                    num++;
                }
            }
            if(num == Resources_Size){
                for (int i = 0; i < this.Resources_Size ; i++) {
                    Available[0][i] = Allocation[count][i]+Available[0][i];
                }

                for (int i = 0; i < this.processes_Size; i++) {
                    for (int j = 0; j < this.Resources_Size; j++) {
                        if(i < count){
                            Need[i][j] = Need[i][j];
                            Allocation[i][j] = Allocation[i][j];
                            processes[i] = processes[i];
                        }else {
                        Need[i][j] = Need[i+1][j];
                        Allocation[i][j] = Allocation[i+1][j];
                        processes[i] = processes[i+1];
                        }
                    }
                }
                processes_Size--;
            }
            num = 0;
            count++;
        }

    }

 

測試用例:

 

 

 申請資源:

 

 

當某個進程所需要的資源全部得到的情況如圖:

 

 

     


免責聲明!

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



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