概述
銀行家算法是荷蘭學者Dijkstra爲銀行系統設計的,以確保銀行在發放現金貸款時,不會發生不能滿足所有客戶需要的情況。後來該算法被用在操作系統中,用於避免死鎖
核心思想
:在進程提出資源申請時,先預判此分配是否會導致系統進入不安全狀態。如果會進入不安全狀態,就暫時不答應這次請求,讓該進程先阻塞等待。
過程演示圖解
假定有五個進程{P0,P1,P2,P3,P4}和三類資源{A,B,C},各種資源的數量分別爲10、5、7。在T0時刻的資源分配情況如下
T0時刻的安全性
P1發出請求向量Request1(1,0,2),系統按銀行家算法進行檢查:
- Request1(1,0,2)<=Need1(1,2,2)
- Request1(1,0,2)<=Available1(3,3,2)
滿足條件。再利用安全性算法檢查此時系統是否安全
銀行家算法
1.數據結構
2. 銀行家算法bank()函數
3.程序共有五部分
代碼實現
#include<stdio.h>
#include <cstdlib>
/*定義數據結構*/
int Max[100][100] ={0};//最大需求矩陣
int Allocation[100][100]={0};//已分配矩陣
int Need[100][100]={0};//需求矩陣
int Available[100]={0}; //資源可用情況
char Name[100]={0};//資源名稱
int Work[100]={0};//記錄系統中當前各類可用資源的數目
int Request[100]={0};//系統對各類資源請求的數目
int Security[100]={0};//保存進程在安全情況下的執行順序
int M;//系統中進程的數量
int N;//資源類型的數量
void init()
{
int i=0,j=0;
printf("請輸入可用資源的種類數量:");
scanf("%d",&N);
for(i=0;i<N;i++)
{
printf("請輸入第 %d 個可用資源的名稱: ",i);
scanf("%s",&Name[i]);
printf("請輸入初始可用資源 %c 的數量: ",Name[i]);
scanf("%d",&Available[i]);
}
printf("\n");
printf("請輸入進程的數量:");
scanf("%d",&M);
printf("請輸入進程的Max矩陣:\n");
for(i=0;i<M;i++){//遍歷每一個進程
for(j=0;j<N;j++){//輸入第i個進程中每種資源的數量
scanf("%d",&Max[i][j]);
}
}
printf("請輸入進程的Allocation矩陣:\n");
int temp[100]={0};//爲了算新的Available
for(i=0;i<M;i++){//遍歷每一個進程
for(j=0;j<N;j++){//輸入第i個進程中每種資源的數量
scanf("%d",&Allocation[i][j]);
//第一個進程需要j類資源的數量:最大需求量-已經分配的
Need[i][j]=Max[i][j]-Allocation[i][j];
temp[j]+=Allocation[i][j]; //統計已經分配的資源量
}
}
for(j=0;j<N;j++)//更新可用資源數目Available
{
Available[j]=Available[j]-temp[j];
}
}
void show(){//功能:進行資源及進程相關信息顯示
printf("\t--------------------\n");
printf("\t系統當前可用的資源矩陣Available:\n");
int i;
for(i=0;i<N;i++){
printf("%c ",Name[i]);
}
printf("\n");
for(i=0;i<N;i++)
printf("%d ",Available[i]);
printf("\n");
printf("\t系統當前資源分配情況如下: \n");
printf("\t Max Allocation Need\n");
printf("進程名 ");
int j=0;
for(j=0;j<3;j++)//每個進程名要輸出三次
{
for(i=0;i<N;i++){//遍歷所有的資源名稱
printf("%c ",Name[i]);
}
}
printf("\n");
for(i=0;i<M;i++){//打印進程
printf("P%d ",i);
for(j=0;j<N;j++){
printf("%d ",Max[i][j]);
}
for(j=0;j<N;j++){
printf("%d ",Allocation[i][j]);
}
for(j=0;j<N;j++){
printf("%d ",Need[i][j]);
}
printf("\n");
}
}
int safe()
{
int Finish[100]={0};//Finish:系統是否有足夠的資源分配給進程,使之完成運行
// 開始時先令Finish[i]=0,當有祖國資源分配給進程時,再令Finish[i]=1
int i=0;
for(i=0;i<N;i++)
{
Work[i]=Available[i];//在執行安全算法開始時,Work=Available
}
int j=0,count=0,k=0,m=0;
for(i=0;i<M;i++)
{
count=0;//遍歷完一個進程就將count置爲0,對新的i號進程資源達標數進行計數
for(j=0;j<N;j++){
//Finish[i]=0表示未執行
if(Finish[i]==0&&Need[i][j]<=Work[j])
{//如果進程沒有執行且資源需求條件滿足
count++;//統計有多少種資源滿足條件
if(count==N) //表示對於i號進程所有資源都滿足
{
Finish[i]=1;//記錄i號進程爲可執行
for(k=0;k<N;k++)
{
Work[k]=Work[k]+Allocation[i][k];
}
Security[m]=i;//記錄第m個執行的是i號進程
i=-1;//將i置爲-1;通過for循環執行i++後變爲0,從第一個進程重新開始找
m++;
}
}
}
}
for(i=0;i<M;i++)
{
if(Finish[i]==0)
{
printf("系統不安全\n");
return -1;
}
}
printf("系統時安全的\n");
for(i=0;i<M;i++)
{
printf("P%d",Security[i]);
if(i<M-1)
printf("-->");
}
printf("\n");
return 0;
}
bool bank()
{
printf("請輸入希望手動分配資源的進程的編號:");
int Id,j;
bool flag=true;
while(scanf("%d",&Id))
{
if(Id < 0 || Id > M-1)
printf("進程不存在!請重新輸入\n請輸入希望手動分配資源的進程的編號:");
else break;
}
printf("請輸入請求資源數(%d個):\n",N);
for(j=0;j<N;j++)
{
scanf("%d",&Request[j]);
}
printf("開始爲進程P%d分配資源:\n",Id);
for(j=0;j<N;j++)
{
if(Request[j]>Need[Id][j]){
printf("進程請求資源數大於所需資源數,無法分配!\n");
flag=false;
break;
}
else if(Request[j]>Available[j]){
printf("進程請求資源數大於可用資源數,無法分配!\n");
flag=false;
break;
}
else{
Available[j] -= Request[j];
Allocation[Id][j] += Request[j];
Need[Id][j] -= Request[j];
}
}
return flag;
}
int main()
{
printf("\t--------------------------\n");
printf("\t|| ||\n");
printf("\t|| 模擬銀行家算法 ||\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t|| Sparky ||\n");
printf("\t|| ||\n");
printf("\t--------------------------\n");
init();
show();
safe();
char choice;
printf("\t-------------------------------------\n");
printf("\t|| ||\n");
printf("\t|| 手動進行資源請求 ||\n");
printf("\t|| 輸入R(r)請求資源 ||\n");
printf("\t|| 輸入E(e)退出程序 ||\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t-------------------------------------\n");
while(true){
printf("請選擇資源分配還是退出");
scanf("%s",&choice);
if(choice=='R'||choice=='r')
{
if(bank()){
safe();
show();
//exit(0);
}else{//說明沒有分配資源,不必退出程序。
show();
}
}
else if(choice=='E'||choice=='e')
{
exit(0);
}
else
printf("請正確選擇");
}
return 0;
}
附簡單測試案例
運行結果
3種資源:
A B C
10 5 7
Max矩陣
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
Allocation
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2