日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

操作系统之银行家算法—详解流程及案例数据

發布時間:2025/3/20 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统之银行家算法—详解流程及案例数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

操作系統之進程調度——優先權法和輪轉法(附上樣例講解)
操作系統之銀行家算法—詳解流程及案例數據
操作系統之多線程編程—讀者優先/寫者優先詳解
操作系統之存儲管理——FIFO算法和LRU算法
操作系統之磁盤調度——SCAN實例講解

要求

銀行家是操作系統比較經典的算法之一,他比較好的防止死鎖情況的出現,增加了系統的安全性.在編寫銀行家算法的過程中,對操作系統的銀行家算法有了深入了解和心得。

一、實驗目的
死鎖會引起計算機工作僵死,因此操作系統中必須防止。本實驗的目的在于讓學生獨立的使用高級語言編寫和調試一個系統動態分配資源的簡單模擬程序,了解死鎖產生的條件和原因,并采用銀行家算法有效地防止死鎖的發生,以加深對課堂上所講授的知識的理解。
二、實驗要求
設計有n個進程共享m個系統資源的系統,進程可動態的申請和釋放資源,系統按各進程的申請動態的分配資源。
系統能顯示各個進程申請和釋放資源,以及系統動態分配資源的過程,便于用戶觀察和分析;
三、數據結構
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。Allocation i表示進程i的分配向量,有矩陣Allocation的第i行構成。
4.需求矩陣Need,這是一個n×m的矩陣,用以表示每個進程還需要的各類資源的數目。如果Need(i,j)=k,表示進程i還需要Rj類資源k個,才能完成其任務。Need i表示進程i的需求向量,由矩陣Need的第i行構成。
上述三個矩陣間存在關系:Need(i,j)=Max(i,j)-Allocation(i,j);
四、安全性算法
1.設置兩個向量。
Work:它表示系統可提供給進程繼續運行的各類資源數目,它包含m個元素,開始執行安全性算法時,Work = Available。
Finish:它表示系統是否有足夠的資源分配給進程,使之運行完成,開始Finish(I)=false;當有足夠資源分配給進程Pi時,令Finish(i)=true;
2.從進程集合中找到一個能滿足下述條件的進程。
Finish(i)= = false;
Need i ≤work;
如找到則執行步驟3;否則,執行步驟4;
3.當進程Pi獲得資源后,可順利執行直到完成,并釋放出分配給它的資源,故應執行
Work = work Allocation i
Finish(i)=true;轉向步驟2;
4.若所有進程的Finish(i)都為true,則表示系統處于安全狀態;否則,系統處于不安全狀態。

流程圖:

個人覺得。總的來說,銀行家算法就是一個模擬借錢。判斷假如借錢是否安全然后考慮借不借的問題。
先放代碼,和數據再說分析:

代碼

import java.util.ArrayDeque; import java.util.Queue; import java.util.Scanner; public class bank {static Scanner sc=new Scanner(System.in);static int n;static int m;static int available[];static int max[][];//最大需求矩陣static int allocation[][];//當前分配到每一個進程的static int need[][];//需求矩陣static boolean isrelesed[];//資源是否已經釋放public static void main(String[] args) {// TODO 自動生成的方法存根 System.out.println("請輸入資源種類m:");m=sc.nextInt();//系統資源initm(m);//初始相關System.out.println("輸入進程數量");n=sc.nextInt();//進程數量initn(n);//初始相關矩陣//getstatus();//輸出當前狀態while(true) {applyresouse();//申請資源}}static void applyresouse()//申請資源{getstatus();//輸出狀態int request[]=new int[m];//需求量 為了節省空間寫成全部變量System.out.println("輸入你想申請資源的編號");int index=sc.nextInt();while(0>index||index>=n) {System.out.println("輸入的編號不在編號范圍之內,請重新輸入");index=sc.nextInt(); }while(isrelesed[index]) {System.out.println("改編號已經完成資源的釋放,無法再請求資源,請重新輸入");index=sc.nextInt();while(0>index||index>=n) {System.out.println("輸入的編號不在編號范圍之內,請重新輸入");index=sc.nextInt(); }}System.out.println("請輸入"+m+"個資源申請的個數(不申請的資源用0替代)");int team=0;while(team==0) {for(int i=0;i<m;i++){request[i]=sc.nextInt();if(request[i]>available[i]) {team=1;}if(request[i]>max[index][i]) {team=2;}}if(team==1) {System.out.println("您的請求量超出 了系統提供量,請重新輸入");team=0;}//重新循環else if(team==2) {System.out.println("您的請求量超出 了最大請求量max,請重新輸入");team=0;}else team=3;//退出循環用}//賦值成功后開始boolean isfinish= ifallocate(index,request);if(isfinish) {System.out.println("所有進程完成資源分配,分配結束");System.exit(0);}} private static boolean ifallocate(int index,int[] request) {//假設分配/** 首先要將真的數組克隆,模擬已經給資源,然后判斷這個資源是否安全*/int work[]=available.clone();boolean finish[]=isrelesed.clone();//克隆初始狀態int need2[][]=new int[n][m];int allocate2[][]=new int[n][m];for(int i=0;i<n;i++){need2[i]=need[i].clone();allocate2[i]=allocation[i].clone();}for(int i=0;i<m;i++){if(need[index][i]<request[i])request[i]=need[index][i];//可以借這么多錢但是我不需要這么多錢anwork[i]-=request[i];//假設把錢借出去allocate2[index][i]+=request[i];}//需要把need2重置一下for(int i=0;i<m;i++){need2[index][i]-=request[i];}boolean isallocate=issafety(work, finish, need2, allocate2);if(!isallocate) {System.out.println("分配造成進程不安全,取消分配"); return false;}else {System.out.println("分配成功");//分配成功就要分配資源for(int i=0;i<m;i++){available[i]-=request[i];allocation[index][i]+=request[i];need[index][i]-=request[i];//System.out.println(request[i]);}if(!isrelesed[index])//判斷改資源是否釋放{boolean jud=false;for(int j=0;j<m;j++){if(need[index][j]!=0)jud=true;}if(!jud)//資源需要釋放 {isrelesed[index]=true;for(int j=0;j<m;j++){available[j]+=allocation[index][j];}}} }boolean isfinished=true;for(int i=0;i<n;i++){for(int j=0;j<m;j++) {if(need[i][j]!=0) {isfinished=false;return false;}}}return isfinished;}private static boolean issafety(int work[],boolean finish[],int need2[][],int allocate2[][])//模擬的需求和分配{//int work[]=available.clone();//不能直接等于復制。可以了解下對象克隆或者深淺復制。Queue<Integer>q1=new ArrayDeque<Integer>();//如果能完成的隊列int time=0;while(true){boolean loop=true;for(int i=0;i<n;i++)//n個進程模擬{time++;if(!finish[i]) {boolean b=false;//完成不了的for(int j=0;j<m;j++){if(work[j]<need2[i][j]){b=true;//完成不了的}if(b) {break;}}if(!b) {//可以完成的,釋放資源time=0;//重新計數q1.add(i);finish[i]=true;//已經完成for(int j=0;j<m;j++){work[j]+=allocate2[i][j];//allocate2[i][j]+=need2[i][j];need2[i][j]=0;}//打印System.out.print("進程"+i+" max:");for(int j=0;j<m;j++){System.out.print(max[i][j]+" ");}System.out.print("allocate2: ");for(int j=0;j<m;j++){System.out.print(allocate2[i][j]+" ");}System.out.print("need2: ");for(int j=0;j<m;j++){System.out.print(need2[i][j]+" ");}System.out.print("work: ");for(int j=0;j<m;j++){System.out.print(work[j]+" ");}System.out.println();}}}boolean isfinish=false;for(int i=0;i<n;i++) {if(!finish[i]) {isfinish=true;break;}}if(!isfinish) {return true;}if(time>n) {return false;}}//return false;}static void initm(int m){System.out.println("請輸入"+m+"種資源的最大量");available=new int[m];isrelesed=new boolean[m];//request=new int[m];for(int i=0;i<m;i++)//初始aviliable{available[i]=sc.nextInt();}}static void initn(int n){max=new int[n][m];allocation=new int[n][m];need=new int[n][m];//finish=new boolean[n];for(int i=0;i<n;i++){System.out.println("進程"+i+"的最大需求為:(輸入m個數)");boolean jud=false;//判斷輸出是否有誤for(int j=0;j<m;j++){max[i][j]=sc.nextInt();if(max[i][j]>available[j]) {jud=true;}}if(jud) {System.out.println("最大需求輸入有誤,請重新賦值(m個數)");i--;}//i自減滿足條件}System.out.println("n個線程m種資源最大需求賦值完成\n請輸入當前進程已分配資源情況");//初始maxfor(int i=0;i<n;i++)//初始allocate矩陣{System.out.println("進程"+i+"已分配資源為:(輸入m個數)");boolean jud=false;for(int j=0;j<m;j++){allocation[i][j]=sc.nextInt();if(allocation[i][j]>max[i][j]){jud=true;}}if(jud) {System.out.println("輸入有誤,請重新輸入");i--;}//輸入有錯誤}System.out.println("allocate(當前已分配矩陣已經分配完畢)");}static void getstatus()//輸出狀態{for(int i=0;i<n;i++){for(int j=0;j<m;j++){need[i][j]=max[i][j]-allocation[i][j];}}for(int i=0;i<n;i++){System.out.print("進程"+i+"的狀態為:max: ");for(int j=0;j<m;j++) {System.out.print(" "+max[i][j]+" ");}System.out.print("allocatem: ");for(int j=0;j<m;j++) {System.out.print(" "+allocation[i][j]+" ");}System.out.print("need: ");for(int j=0;j<m;j++) {System.out.print(" "+need[i][j]+" ");}System.out.print("avaliable: ");for(int j=0;j<m;j++) {System.out.print(" "+available[j]+" ");}System.out.println();}} }

分析

A還—>借B—>B還—>C—這樣可以到最后。但是很多情況下客戶是分期借的,這就要考慮安全性問題,比如A借6,6,6還剩4,4,4那么這個銀行做多最多只能借2,2,2給其他人,因為一旦借多了A也無法釋放,那么就造成死鎖。那么這種情況就不能夠借錢。所以在借錢的時候需要一個模擬的過程。

  • 還有比較重要的是明白銀行加算法各個矩陣的意義和作用非常的重要,我剛開始看銀行家算法的時候因為對一些基礎概念和數組矩陣的屬性不夠了解,茫然了很久,也走了很多的坑。那么就先介紹一下吧。
  • 對于全局變量,我的代碼中有:
  • 這些變量是在安全狀態下的真實變量其中:
  • (1)n是線程的數量,m是資源的種類。
  • Available[]是當前還可以使用的資源。也就是銀行家手中被借出去錢,手中還剩余各種錢的數量。只跟資源有關
  • Max[][]是最大需求矩陣,也可以理解為最終終態矩陣,因為這個max的狀態就是客戶想達到和滿足的狀態。也就是線程可以釋放的狀態。
  • Allocate[][]是已分配矩陣。就是客戶已經借到的錢。也就是線程已經占有的資源量
  • Need[][]是還需要資源情況,由max和allcate決定。
  • Isrelese[]這個數組和線程有關和資源無關,它記錄的就是線程是否達到終態,完成資源釋放的情況,,一旦完成借錢就不需要借錢。
  • 3:最后在具體實現的過程中。由于需要模擬過程,還是會遇到挺多坎的,在理清思路之后。在代碼上還是由挺多要注意的。
    第一:對象克隆(深淺拷貝),在模擬的過程中擁有初始化和真實數據一樣的數組。但是如果直接賦值那么新對象指向的還是老數組的地址,會造成數據紊亂。那么對象克隆就一定要保證只賦值數據,不復制地址。
    第二:模擬數值的改變,無論在申請資源,還是釋放資源的時候,模擬的數值都會改變。但是不過如果模擬成功,真實數組會增加多少。這個需要尤其注意,同時,如果發現數值和預期不符合可以打斷點單步調試。

附上我自己的流程圖:
初始化:

借錢:

ps:本人有點菜,這里面可能有挺多的是錯誤的。。如果有大佬發現請指正。

如果對后端、爬蟲、數據結構算法等感性趣歡迎關注我的個人公眾號交流:bigsai

總結

以上是生活随笔為你收集整理的操作系统之银行家算法—详解流程及案例数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。