銀行家算法
一、基本概念:
Dijkstra 的銀行家算法是避免死鎖最具有代表性的算法。起這樣的名字是由於該算法原本是為銀行系統設計的。以確保銀行在發放現金貸款時,不會發生不能滿足所有客戶需要的情況。在OS中也可以用它來實現避免死鎖。
二、數據結構:
(1)一個Available數組。這是一個含有M個元素的數組,其中的每一個元素均可代表可利用的資源數目。
(2)最大需求Max矩陣。這是一個n x m 的矩陣,它定義了系統中N個進程中,每個進程對m類資源的最大需求。如果Max[i,j]=K,則表示進程i需要Rj類資源的最大數組為K。
(3)分配矩陣Allocation。這也是一個n x m 的矩陣它定義了系統中每一類水資源當前已分配給每一進程的資源數。如果Allocation[i,j]=K,則表示進程I 當前已分得Rj類資源的數目為K。
(4)需求矩陣Need。這也是一個n x m 的矩陣,用以表示每一個進程尚需的各類資源數。如果Need[i,j]=K,則表示進程i還需要Rj類資源K個方能完成任務。
三、銀行家算法實現:
設Request i是進程Pi的請求向量,如果Rquesti[j]=K,表示進程P需要K個Rj類型的資源。當Pi發出資源請求后,系統按以下步驟進行分配。
Available[j] = Available[j]-Request[j]; Allocation[i,j] = Allocation[i,j]+Request[j]; Need[i,j] = Need[i,j]-Requesti[j];
分配之后執行安全性算法檢測:
安全性算法數據結構:
(1)設置一個工作向量Work 初始化為 Work = Available
(2)Finish 數組,表示系統是否有足夠的資源分配給進程,使之運行完成。初始化為false,有足夠資源分配給進程時再令Finish[i]=true;
安全性算法:
從進程集合中找出一個進程:滿足下列條件:
1、Finish[I] = false;
2、Need[i,j] <= Work[j];
隨后當進程Pi獲得資源后,可順利執行,直至完成,並釋放出資源,因此需要執行:
Work[j] = Work[j]+Allocation[i,j]l;
Finish[i] = true;
然后重復以上步驟。
如果Finish數組均滿足=true;則安全,否則不安全!
下面給出Javascript的實現代碼。
<!DOCTYPE html> <html> <head> <title>銀行家算法</title> <meta charset="UTF-8"> </head> <script type="text/javascript"> core=new Object(); core.Max=[[7,5,3],[3,2,2],[9,0,2],[2,2,2],[4,3,3]]; core.Allocation=[[0,1,0],[2,0,0],[3,0,2],[2,1,1],[0,0,2]]; core.Need=[[7,4,3],[1,2,2],[6,0,0],[0,1,1],[4,3,1]]; core.Available=[3,3,2]; /* 打印 */ function printCore(){ document.write("<table border=\"1\"><tr><th></th><th>Max</th><th>Allocation</th><th>Need</th><th>Available</th></tr>") for(var i=0;i<core.Max.length;i++){ document.write("<tr>"); document.write("<td>p"+i+"</td>"); document.write("<td>"+core.Max[i]+"</td>"); document.write("<td>"+core.Allocation[i]+"</td>"); document.write("<td>"+core.Need[i]+"</td>"); if(i==0){ document.write("<td>"+core.Available+"</td>"); } document.write("</tr>") } document.write("</table>") } /* request 第一次檢驗 */ function request1(p,request) { var sign; for (var i=0;i<core.Need.length;i++) { if(p==i){ for(var j=0;j<core.Available.length;j++){ if(request[j]>core.Need[i][j]){ sign=1; break; } } } } if(sign==1){ document.write("它所需要的資源數已經超過宣布的最大值"); }else{ request2(p,request); } } /* request 第二次檢驗 */ function request2(p,request){ var sign; for(var i=0;i<core.Available.length;i++){ if(request[i]>core.Available[i]){ sign=1; break; } } if (sign==1) { document.write("尚無足夠的資源,進程需要等待"); }else{ fenpei(p,request); } } /* 嘗試分配: */ function fenpei(p,request){ for (var i=0;i<core.Need.length;i++) { if(p==i){ for(var j=0;j<core.Available.length;j++){ core.Available[j]=core.Available[j]-request[j]; core.Allocation[i][j] = core.Allocation[i][j]+request[j]; core.Need[i][j]=core.Need[i][j]-request[j]; } } } } /* 安全性檢測 */ function secCheck(){ var work = new Array(); var works = new Array(core.Allocation.length); for(var i=0;i<works.length;i++){ works[i] = new Array(); } for(var i=0;i<core.Available.length;i++){ work.push(core.Available[i]); } var Finish = new Array(core.Allocation.length); for(var i=0;i<Finish.length;i++){ Finish[i]=false; } var find = 0; var arr = new Array(); while(find!=-1){ here: for (var i = 0; i < Finish.length; i++) { if (Finish[i]==false&&__sec(i,work)) { find = i; arr.push(find); break here; } else { find = -1; } } if (find != -1) { for (var j = 0; j < work.length; j++) { work[j] = work[j] + core.Allocation[find][j]; Finish[find] = true; } for(var j=0;j<core.Available.length;j++){ works[find][j] = work[j]; } } } for(var i=0;i<Finish.length;i++){ if(Finish[i]==false) { document.write("<h3 style=\"color:#FF0000\">安全性檢測不通過!</h3>"); return; } } document.write("<table border=\"1\"><tr><th></th><th>Max</th><th>Need</th><th>Allocation</th><th>Work+Allocation</th><th>finish</th></tr>"); for(var i= 0;i<Finish.length;i++){ document.write("<tr>"); document.write("<td>p"+arr[i]+"</td>") document.write("<td>"+core.Max[arr[i]]+"</td>"); document.write("<td>"+core.Need[arr[i]]+"</td>"); document.write("<td>"+core.Allocation[arr[i]]+"</td>"); document.write("<td>"+works[arr[i]]+"</td>"); document.write("<td>"+Finish[arr[i]]+"</td>"); document.write("</tr>"); } document.write("</table>"); } function __sec(i,work){ for(var j=0;j<work.length;j++){ if(work[j]<core.Need[i][j]) return false; } return true; } </script> <body> <script type="text/javascript"> document.write("<h3>T0時刻、初始化為:</h3>"); printCore(); document.write("<h3>T0時刻、安全檢測結果為</h3>"); secCheck(); document.write("<h3>進程P1的request向量設置為:1,0,2。<h3>"); request=[1,0,2]; request1(1,request); document.write("<h3>T1分配后狀態為:</h3>"); printCore(); secCheck(); document.write("<h3>P4請求資源 request 向量設置為 3,3,0</h3>"); request=[3,3,0]; request1(4,request); document.write("<h3>p0請求資源,request向量設置為 0,2,0</h3>"); request=[0,2,0]; request1(0,request); printCore(); secCheck(); </script> </body> </html>
運行結果如下: