操作系統中避免死鎖的銀行家算法【表面C++實際C語言】一學就廢的菜雞代碼

文章目錄

  • 銀行家算法
  • 實驗原理
    • 數據結構
    • 初始化
    • 輸出資源分配量
    • 安全性算法
    • 銀行家算法
  • 完整代碼
  • 測試數據
  • 測試結果
    • 第一題
    • 第二題


銀行家算法

銀行家算法是一種最有代表性的避免死鎖的算法。在避免死鎖方法中允許進程動態地申請資源,但系統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。(破壞了環路等待條件)


實驗原理


數據結構

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]

int Allocation[11][101];//進程已獲得資源
int Max[11][101];//進程所需最大資源
int Available[11];//可分配資源
int Need[11][101];//進程所需資源
int Requesti[11];//資源請求
int Work[11];//工作向量
int link[11];//安全序列
int x,y;//x表進程數,y表資源種類

初始化

幫助用戶輸入已知變量的函數,構建銀行家算法的Max、Allocation、Need、Available矩陣,便于進行接下來的數據處理。

void init(){//初始化cout << "請輸入進程個數:" << endl;cin >> x;cout << "請輸入資源共有多少類:" << endl;cin >> y;cout << "請輸入每個進程所需要的各種資源的最大數目:" << endl;for (int i = 0; i < x; i++) {cout << "P" << i+1 << ":" ;for (int j = 0; j < y; j++) {cin >> Max[i][j];}}cout << "請輸入每個進程已分配的資源數量:" << endl;for(int i=0; i<x; i++){cout << "P" << i+1 << ":" ;for(int j=0; j<y; j++){cin >> Allocation[i][j];if(Allocation[i][j]>Max[i][j]){cout << "已分配資源數量大于進程所需的資源最大數目,請重新輸入" << endl;i--;}}}cout << "請輸入系統可分配的資源數:" << endl;for (int i = 0; i < y; i++) {cin >> Available[i];}for (int i = 0; i < x; i++) {//計算每一個進程尚需的各類資源數,Need矩陣for (int j = 0; j < y; j++) {Need[i][j] = Max[i][j] - Allocation[i][j];}}
}

輸出資源分配量

打印現在的矩陣狀態(Max、Allocation、Need、Available),方便用戶了解算法進行程度

void printSystemVariable(){//輸出資源分配量cout << "此時資源分配量如下:" << endl;cout << "進程  " << "   Max   " << "   Alloction " << "    Need  " << "    Available " << endl;for(int i=0;i<x;i++){//第i個進程cout << "P" << i+1 << "     " ;for(int j=0;j<y;j++){//第i個進程的Max矩陣信息cout << Max[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i個進程的Allocation矩陣信息cout << Allocation[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i個進程的Need矩陣信息cout << Need[i][j] << "    " ;}cout << "|  " ;if(i==0){for(int j=0;j<y;j++){//第i個進程的Available矩陣信息cout << Available[j] << "    " ;}}cout << endl ;}
}

安全性算法

1)設置兩個向量:
工作向量Work: 它表示系統可提供給進程繼續運行所需的各類資源數目,它含有m個元素,在執行安全算法開始時,Work=Available;
工作向量Finish: 它表示系統是否有足夠的資源分配給進程,使之運行完成。開始時先做Finish[i]=false; 當有足夠資源分配給進程時, 再令Finish[i]=true
2)從進程集合中找到一個能滿足下述條件的進程:
Finish[i]=false;
Need[i,j]≤Work[j];
若找到,執行 (3),否則,執行 (4)
3)當進程Pi獲得資源后,可順利執行,直至完成,并釋放出分配給它的資源,故應執行:
Work[j]=Work[i]+Allocation[i,j];
Finish[i]=true;
go to step 2;

4)如果所有進程的Finish[i]=true都滿足, 則表示系統處于安全狀態;否則,系統處于不安全狀態

bool chesksafe(){//安全性算法for (int i = 0; i < y; i++) {Work[i] = Available[i];}bool Finish[7];//工作向量int mark = x;//避免改變x的值所設的變量int temp = 0;//滿足需求資源少于剩余資源這一條件的資源數int flag = 0;//進行資源分配的次數while (mark--) {//求安全序列的操作最多進行進程數次for(int i=0;i<x;++i){//判定第i個進程if(Finish[i]==true){continue;}for (int j = 0; j < y; j++) {if(Need[i][j]<=Work[j]){//計算該進程需求資源少于剩余資源的資源數temp++;}}if(temp==y){//全部資源都滿足需求資源少于剩余資源for (int j = 0; j < y; j++) {//獲得分配給該資源的資源數Work[j]+=Allocation[i][j];}Finish[i]=true;flag++;//進行一次資源分配link[flag]=i+1;//將進行資源分配的進程依次放入隊列}temp=0;//更新滿足分配資源條件的資源數}}if(flag==x){//如果沒有進行進程數次資源分配,說明不是安全序列cout << "系統處于安全狀態,安全序列為:" << endl;for (int i = 1; i <= x; i++) {cout << "P" << link[i] << " " ;}cout << endl;return true;}else{cout << "系統處于不安全狀態" << endl;return false;}
}

銀行家算法

設Requesti是進程Pi的請求向量,如果Requesti[j]=K,表示進程Pi需要K個Rj類型的資源。當Pi發出資源請求后,系統按下述步驟進行檢查:
(1)如果Requesti[j]≤Need[i,j],便轉向步驟(2);否則認為出錯,因為它所需要的資源數已超過它所宣布最大值。
(2)如果Requesti[j]≤Available[j],便轉向步驟(3);否則,表示尚無足夠資源,Pi須等待。
(3)系統試探著把資源分配給進程Pi,并修改下面數據結構中的數值:
Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];

系統執行安全性算法,檢查此次資源分配后,系統是否處于安全狀態。若安全,才正式將資源分配給進程Pi,以完成本次分配;否則,將本次的試探分配作廢,恢復原來的資源分配狀態,讓進程Pi等待。

  string an;//存儲是否請求分配的用戶指令bool flag = false;//用于跳出兩層循環的標志while(1){cout << "是否請求分配?('y'or'Y'表是,'n'or'N'表否) " ;cin>>an;if(an[0]!='Y'&&an[0]!='y'){break;}int num;cout << "請輸入請求資源的進程號(如:P1則輸入1): " << endl;cin >> num;num -= 1;//進程從1開始計數但各個數組下標從0開始計數cout << "輸入進程請求的資源數" << endl;for (int i = 0; i < y; i++) {cin >> Requesti[i];}for (int i = 0; i < y; i++) {if(Requesti[i]>Need[num][i]){cout << "所需要的資源數已超過所宣布最大值Max" << endl;flag = true;break;}if(Requesti[i]>Available[i]){cout << "尚無足夠資源" << endl;flag = true;break;}Available[i]-=Requesti[i];Allocation[num][i]+=Requesti[i];Need[num][i]-=Requesti[i];}if (flag){//當任意資源請求出現問題時,跳出兩層循環flag = false;//更新標志continue;//執行下一次循環}int temp = 0;//滿足Max值的Allocation值的個數if(chesksafe()){//安全,完成本次分配for (int i = 0; i < y; i++) {if(Allocation[num][i]>=Max[num][i]){temp++;}}if (temp == y) {/*如果1個進程分配資源后,每個資源已獲得值都大于等于所需最大值則更新Available、Allocation和Need矩陣*/for (int i = 0; i < y; i++) {Available[i]+=Allocation[num][i];//可分配資源獲得該進程已獲得的資源數Allocation[num][i]=0;//清空該進程已獲得的資源數Need[num][i]=0;//清空該進程尚需的各類資源數}}cout << "分配成功" << endl;printSystemVariable();}else{//不安全,撤銷之前的操作cout << "分配失敗" << endl;for (int i = 0; i < y; i++) {Available[i]+=Requesti[i];Need[num][i]+=Requesti[i];Allocation[num][i]-=Requesti[i];}printSystemVariable();}}

完整代碼

#include <iostream>
using namespace std;int Allocation[11][101];//進程已獲得資源
int Max[11][101];//進程所需最大資源
int Available[11];//可分配資源
int Need[11][101];//進程所需資源
int Requesti[11];//資源請求
int Work[11];//工作向量
int link[11];//安全序列
int x,y;//x表進程數,y表資源種類void init();//初始化
void printSystemVariable();//輸出資源分配量
bool chesksafe();//安全性算法int main(int argc, char const *argv[]) {init();printSystemVariable();if(!chesksafe()){return 0;}string an;//存儲是否請求分配的用戶指令bool flag = false;//用于跳出兩層循環的標志while(1){cout << "是否請求分配?('y'or'Y'表是,'n'or'N'表否) " ;cin>>an;if(an[0]!='Y'&&an[0]!='y'){break;}int num;cout << "請輸入請求資源的進程號(如:P1則輸入1): " << endl;cin >> num;num -= 1;//進程從1開始計數但各個數組下標從0開始計數cout << "輸入進程請求的資源數" << endl;for (int i = 0; i < y; i++) {cin >> Requesti[i];}for (int i = 0; i < y; i++) {if(Requesti[i]>Need[num][i]){cout << "所需要的資源數已超過所宣布最大值Max" << endl;flag = true;break;}if(Requesti[i]>Available[i]){cout << "尚無足夠資源" << endl;flag = true;break;}Available[i]-=Requesti[i];Allocation[num][i]+=Requesti[i];Need[num][i]-=Requesti[i];}if (flag){//當任意資源請求出現問題時,跳出兩層循環flag = false;//更新標志continue;//執行下一次循環}int temp = 0;//滿足Max值的Allocation值的個數if(chesksafe()){//安全,完成本次分配for (int i = 0; i < y; i++) {if(Allocation[num][i]>=Max[num][i]){temp++;}}if (temp == y) {/*如果1個進程分配資源后,每個資源已獲得值都大于等于所需最大值則更新Available、Allocation和Need矩陣*/for (int i = 0; i < y; i++) {Available[i]+=Allocation[num][i];//可分配資源獲得該進程已獲得的資源數Allocation[num][i]=0;//清空該進程已獲得的資源數Need[num][i]=0;//清空該進程尚需的各類資源數}}cout << "分配成功" << endl;printSystemVariable();}else{//不安全,撤銷之前的操作cout << "分配失敗,撤銷本次操作" << endl;for (int i = 0; i < y; i++) {Available[i]+=Requesti[i];Need[num][i]+=Requesti[i];Allocation[num][i]-=Requesti[i];}printSystemVariable();}}return 0;
}void init(){//初始化cout << "請輸入進程個數:" << endl;cin >> x;cout << "請輸入資源共有多少類:" << endl;cin >> y;cout << "請輸入每個進程所需要的各種資源的最大數目:" << endl;for (int i = 0; i < x; i++) {cout << "P" << i+1 << ":" ;for (int j = 0; j < y; j++) {cin >> Max[i][j];}}cout << "請輸入每個進程已分配的資源數量:" << endl;for(int i=0; i<x; i++){cout << "P" << i+1 << ":" ;for(int j=0; j<y; j++){cin >> Allocation[i][j];if(Allocation[i][j]>Max[i][j]){cout << "已分配資源數量大于進程所需的資源最大數目,請重新輸入" << endl;i--;}}}cout << "請輸入系統可分配的資源數:" << endl;for (int i = 0; i < y; i++) {cin >> Available[i];}for (int i = 0; i < x; i++) {//計算每一個進程尚需的各類資源數,Need矩陣for (int j = 0; j < y; j++) {Need[i][j] = Max[i][j] - Allocation[i][j];}}
}void printSystemVariable(){//輸出資源分配量cout << "此時資源分配量如下:" << endl;cout << "進程  " << "   Max   " << "   Alloction " << "    Need  " << "    Available " << endl;for(int i=0;i<x;i++){//第i個進程cout << "P" << i+1 << "     " ;for(int j=0;j<y;j++){//第i個進程的Max矩陣信息cout << Max[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i個進程的Allocation矩陣信息cout << Allocation[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i個進程的Need矩陣信息cout << Need[i][j] << "    " ;}cout << "|  " ;if(i==0){for(int j=0;j<y;j++){//第i個進程的Available矩陣信息cout << Available[j] << "    " ;}}cout << endl ;}
}bool chesksafe(){//安全性算法for (int i = 0; i < y; i++) {Work[i] = Available[i];}bool Finish[7];//工作向量int mark = x;//避免改變x的值所設的變量int temp = 0;//滿足需求資源少于剩余資源這一條件的資源數int flag = 0;//進行資源分配的次數while (mark--) {//求安全序列的操作最多進行進程數次for(int i=0;i<x;++i){//判定第i個進程if(Finish[i]==true){continue;}for (int j = 0; j < y; j++) {if(Need[i][j]<=Work[j]){//計算該進程需求資源少于剩余資源的資源數temp++;}}if(temp==y){//全部資源都滿足需求資源少于剩余資源for (int j = 0; j < y; j++) {//獲得分配給該資源的資源數Work[j]+=Allocation[i][j];}Finish[i]=true;flag++;//進行一次資源分配link[flag]=i+1;//將進行資源分配的進程依次放入隊列}temp=0;//更新滿足分配資源條件的資源數}}if(flag==x){//如果沒有進行進程數次資源分配,說明不是安全序列cout << "系統處于安全狀態,安全序列為:" << endl;for (int i = 1; i <= x; i++) {cout << "P" << link[i] << " " ;}cout << endl;return true;}else{cout << "系統處于不安全狀態" << endl;return false;}
}

測試數據

這里的測試數據就拿教材上的一個習題


測試結果

第一題

在這里插入圖片描述

第二題

注意題中排序從0開始,程序排序從1開始,此題中的P2對應程序中的P3,輸入數字應該是3而不是2

在這里插入圖片描述
經演算結果完全正確√

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443901.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443901.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443901.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GitHub 使用指南

目錄切換分支刪除已有文件只刪除遠程倉庫中的文件&#xff0c;不刪除本地倉庫中的文件同時刪除遠程倉庫和本地倉庫中的文件提交文件git查看本地分支連接的是哪個遠程分支切換分支 查看本地和遠程所有分支 git branch -a當前本地分支為綠色&#xff0c;當前所在分支前帶有“*”號…

百度EBG測試部AI測試工程師面經

百度EBG測試部AI測試工程師 1、自我介紹 自我介紹盡量多說一點&#xff0c;她會問你“還有嗎&#xff1f;” 2、項目介紹 簡歷上的項目都讓介紹了。會問這個項目是做什么的&#xff0c;是由誰開發&#xff0c;項目如何得到的&#xff0c;在測試過程中實現了什么。 3、自己…

一學就廢的并查集它來了

文章目錄題目描述輸入輸出樣例輸入樣例輸出提示算法思想代碼實現尋找根節點匯總連接情況完整代碼關于flag的初值題目描述 某省調查城鎮交通狀況&#xff0c;得到現有城鎮道路統計表&#xff0c;表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城…

一道很簡單的貪心算法題~【貪心:我不要臉的伐?】

文章目錄題目描述輸入輸出樣例輸入樣例輸出C語言代碼實現思路排序處理完整代碼C代碼實現排序完整代碼彩蛋題目描述 小健有一家自己的商店&#xff0c;主營牛奶飲品&#xff0c;最近資金緊張&#xff0c;他想以盡可能低的價格進購足夠的牛奶以供日常的需要。所以小健想要求助你…

Eclipse 中修改java編譯版本

修改方法是&#xff1a; 1&#xff1a;Preferences-->Java-->Compiler->Compiler compliance level&#xff0c;選擇一個需要的版本&#xff0c;比如從默認的1.4改為5.0 2&#xff1a;如果只想修改一個工程的Compiler compliance level,就右單擊工程&#xff0c;選擇屬…

百戰c++(1)

Public和private的區別 public和private是類里的關鍵字&#xff0c;用于規定類內數據或者成員函數的訪問權限。private類型的數據或者函數&#xff0c;只能在相應的類內被訪問&#xff0c;而public類型的數據或者函數被訪問的權限比較寬&#xff0c;還可以在其它類或者其它函數…

一學就廢的三種簡單排序【冒泡、插入、選擇】

文章目錄其他排序算法冒泡排序算法實現代碼實例插入排序算法實現代碼實例選擇排序算法實現代碼實例其他排序算法 一學就廢的歸并排序 冒泡排序 排列順序從前到后或者從后往前都可&#xff0c;本文選擇從后到前的順序&#xff0c;升序排列&#xff1a;比較相鄰兩個元素&#x…

百戰c++(2)

delete 和 delete []的真正區別 delete 對應 new delete[]對應new[]對于簡單類型包括簡單類型數組&#xff0c;delete 與delete[]沒有區別。對于自定義類型數組&#xff0c;delete 只會刪除一個元素&#xff0c;delete 則會刪除所有元素。 指針和數組的區別 野指針是什么 野指…

shell預先定義的特殊變量

文章目錄$#$*$$$# 表示命令行上參數的個數&#xff0c;但不包括shell腳本名本身 為腳本ex1賦予兩個變量&#xff0c;測試$#的輸出結果 [cmybogon test2]$ . ex1 ma.c mb.c 2 # echo $# 7 # cat $1 $2 $3 | wc -l 2 # echo $#腳本ex1的具體內容 [rootlocalhost test]$ cat ex1…

Linux實驗一:常用的Linux命令

文章目錄一、實驗目的二、實驗要求三、實驗內容1、系統的使用2、命令的使用3、文件操作4、系統詢問與權限口令5、其它常用命令四、實驗操作1、基本命令的使用2、文件和目錄操作3、創建用戶帳戶一、實驗目的 1、熟悉Linux的桌面環境&#xff1b; 2、了解Linux所安裝的軟件包 3、…

Linux實驗二:vi編輯器的使用

文章目錄一、實驗目的二、實驗要求三、實驗內容1、創建文件2、編輯文件一、實驗目的 1、練習并掌握Linux提供的vi編輯器來編譯C程序 2、學會利用gcc、gdb編譯、調試C程序 3、本次實驗的目的是讓同學們了解如何使用vi編輯器進行創建和編輯文件 二、實驗要求 1、文件編輯器vi…

百戰c++(os1)

Linux中的鎖 互斥鎖&#xff1a;mutex&#xff0c;用于保證在任何時刻&#xff0c;都只能有一個線程訪問該對象。當獲取鎖操作失敗時&#xff0c;線程會進入睡眠&#xff0c;等待鎖釋放時被喚醒 讀寫鎖&#xff1a;rwlock&#xff0c;分為讀鎖和寫鎖。處于讀操作時&#xff0…

Linux實驗三:Shell編程

文章目錄一、實驗目的二、實驗要求三、實驗內容1、通配符的使用2、重定向3、管道4、shell變量5、建立下面的腳本&#xff0c;運行并分析輸出結果&#xff0c;并給出代碼注釋。6、編寫腳本一、實驗目的 1.為文件擴展名使用通配符 2.標準輸入、標準輸出和標準錯誤的重定向 3.使…

a href=#與 a href=javascript:void(0) 的區別

a href"#"> 點擊鏈接后&#xff0c;頁面會向上滾到頁首&#xff0c;# 默認錨點為 #TOP<a href"javascript:void(0)" onClick"window.open()"> 點擊鏈接后&#xff0c;頁面不動&#xff0c;只打開鏈接<a href"#" οnclick&…

Linux實驗四:編譯和調試工具的使用

文章目錄一、實驗目的&#xff1a;二、實驗要求三、實驗內容四、實驗操作1、用gcc編譯程序&#xff0c;寫出編譯過程&#xff0c;并給出運行結果。2、調試程序&#xff0c;要求用gdb進行調試并給出修改方案。3、make的使用一、實驗目的&#xff1a; 1、練習并掌握Linux提供的v…

Linux實驗五:Linux環境下的C語言編程

文章目錄一、實驗目的&#xff1a;二、實驗要求三、實驗內容1、編寫一段C語言程序使其完成&#xff1a;父進程創建兩個子進程&#xff0c;每個進程都在屏幕上顯示自己的進程ID號。2、上機調試下面的程序&#xff0c;觀察運行結果&#xff0c;分析原因。3、利用兩個管道進行雙向…

百戰c++(4)

1.求下面函數的返回值&#xff08;微軟&#xff09; int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8 思路&#xff1a;將x轉化為2進制&#xff0c;看含有的1的個數。 2. 什么是“引用”&…

ndarray對象的建立

文章目錄ndarray&#xff08;別名array&#xff09;常用屬性創建NumPy數組使用array()函數使用zeros()函數使用ones()函數使用empty()函數使用arange()函數注意ndarray&#xff08;別名array&#xff09; 常用屬性 import numpy as np # Numpy工具包data np.arange(12).res…

百戰c++(5)

11. 已知strcpy的函數原型&#xff1a;char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串&#xff0c;strSrc 是源字符串。不調用C/C 的字符串庫函數&#xff0c;請編寫函數 strcpy。 答案&#xff1a; char *strcpy(char *strDest, const char *strS…

Numpy數組的廣播機制

文章目錄前言數組廣播廣播機制的使用條件前言 Numpy數組不需要循環遍歷&#xff0c;即可對每個元素執行批量的算術運算操作&#xff08;矢量化運算&#xff09;。當兩個數組大小&#xff08;Numpy.shape&#xff09;不同時&#xff0c;進行算術運算會出現廣播機制。 數組廣播…