(一) 目的和要求
銀行家算法是由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 << "若滿足申請,系統將進入不安全狀態,可能導致死鎖!"; } }
