必威电竞|足球世界杯竞猜平台

銀行家算法
來源:互聯(lián)網(wǎng)

銀行家算法(Banker's Algorithm)是一個(gè)避免死鎖(Deadlock)的著名算法,是由艾茲格·迪杰斯特拉在1965年為T.H.E系統(tǒng)設(shè)計(jì)的一種避免死鎖產(chǎn)生的算法。它以銀行借貸系統(tǒng)的分配策略為基礎(chǔ),判斷并保證系統(tǒng)的安全運(yùn)行。

背景簡介

在銀行中,客戶申請(qǐng)貸款的數(shù)量是有限的,每個(gè)客戶在第一次申請(qǐng)貸款時(shí)要聲明完成該項(xiàng)目所需的最大資金量,在滿足所有貸款要求時(shí),客戶應(yīng)及時(shí)歸還。銀行家在客戶申請(qǐng)的貸款數(shù)量不超過自己擁有的最大值時(shí),都應(yīng)盡量滿足客戶的需要。在這樣的描述中,銀行家就好比操作系統(tǒng),資金就是資源,客戶就相當(dāng)于要申請(qǐng)資源的進(jìn)程。

銀行家算法是一種最有代表性的避免死鎖的算法。在避免死鎖方法中允許進(jìn)程動(dòng)態(tài)地申請(qǐng)資源,但系

統(tǒng)在進(jìn)行資源分配之前,應(yīng)先計(jì)算此次分配資源的安全性,若分配不會(huì)導(dǎo)致系統(tǒng)進(jìn)入不安全狀態(tài),則分配,否則等待。為實(shí)現(xiàn)銀行家算法,系統(tǒng)必須設(shè)置若干數(shù)據(jù)結(jié)構(gòu)

要解釋銀行家算法,必須先解釋操作系統(tǒng)安全狀態(tài)和不安全狀態(tài)。

安全序列是指一個(gè)進(jìn)程序列{P1,…,Pn}是安全的,即對(duì)于每一個(gè)進(jìn)程Pi(1≤i≤n),它以后尚需要的資源量不超過系統(tǒng)當(dāng)前剩余資源量與所有進(jìn)程Pj (j < i )當(dāng)前占有資源量之和。

安全狀態(tài)

如果存在一個(gè)由系統(tǒng)中所有進(jìn)程構(gòu)成的安全序列P1,…,Pn,則系統(tǒng)處于安全狀態(tài)。安全狀態(tài)一定是沒有死鎖發(fā)生。

不安全狀態(tài)

不存在一個(gè)安全序列。不安全狀態(tài)不一定導(dǎo)致死鎖。

數(shù)據(jù)結(jié)構(gòu)

1)可利用資源向量Available

是個(gè)含有m個(gè)元素的數(shù)組,其中的每一個(gè)元素代表一類可利用的資源數(shù)目。如果Available[j]=K,則表示系統(tǒng)中現(xiàn)有Rj類資源K個(gè)。

2)最大需求矩陣Max

這是一個(gè)n×m的矩陣,它定義了系統(tǒng)中n個(gè)進(jìn)程中的每一個(gè)進(jìn)程對(duì)m類資源的最大需求。如果Max[i,j]=K,則表示進(jìn)程i需要Rj類資源的最大數(shù)目為K。

3)分配矩陣Allocation

這也是一個(gè)n×m的矩陣,它定義了系統(tǒng)中每一類資源當(dāng)前已分配給每一進(jìn)程的資源數(shù)。如果Allocation[i,j]=K,則表示進(jìn)程i當(dāng)前已分得Rj類資源的 數(shù)目為K。

4)需求矩陣Need。

這也是一個(gè)n×m的矩陣,用以表示每一個(gè)進(jìn)程尚需的各類資源數(shù)。如果Need[i,j]=K,則表示進(jìn)程i還需要Rj類資源K個(gè),方能完成其任務(wù)。

Need[i,j]=Max[i,j]-Allocation[i,j]

算法原理

我們可以把操作系統(tǒng)看作是銀行家,操作系統(tǒng)管理的資源相當(dāng)于銀行家管理的資金,進(jìn)程向操作系統(tǒng)請(qǐng)求分配資源相當(dāng)于用戶向銀行家貸款。

為保證資金的安全,銀行家規(guī)定:

(1) 當(dāng)一個(gè)顧客對(duì)資金的最大需求量不超過銀行家現(xiàn)有的資金時(shí)就可接納該顧客;

(2) 顧客可以分期貸款,但貸款的總數(shù)不能超過最大需求量;

(3) 當(dāng)銀行家現(xiàn)有的資金不能滿足顧客尚需的貸款數(shù)額時(shí),對(duì)顧客的貸款可推遲支付,但總能使顧客在有限的時(shí)間里得到貸款;

(4) 當(dāng)顧客得到所需的全部資金后,一定能在有限的時(shí)間里歸還所有的資金.

操作系統(tǒng)按照銀行家制定的規(guī)則為進(jìn)程分配資源,當(dāng)進(jìn)程首次申請(qǐng)資源時(shí),要測試該進(jìn)程對(duì)資源的最大需求量,如果系統(tǒng)現(xiàn)存的資源可以滿足它的最大需求量則按當(dāng)前的申請(qǐng)量分配資源,否則就推遲分配。當(dāng)進(jìn)程在執(zhí)行中繼續(xù)申請(qǐng)資源時(shí),先測試該進(jìn)程本次申請(qǐng)的資源數(shù)是否超過了該資源所剩余的總量。若超過則拒絕分配資源,若能滿足則按當(dāng)前的申請(qǐng)量分配資源,否則也要推遲分配。

算法實(shí)現(xiàn)

初始化

由用戶輸入數(shù)據(jù),分別對(duì)可利用資源向量矩陣AVAILABLE、最大需求矩陣MAX、分配矩陣ALLOCATION、需求矩陣NEED賦值。

銀行家算法

在避免死鎖的方法中,所施加的限制條件較弱,有可能獲得令人滿意的系統(tǒng)性能。在該方法中把系統(tǒng)的狀態(tài)分為安全狀態(tài)和不安全狀態(tài),只要能使系統(tǒng)始終都處于安全狀態(tài),便可以避免發(fā)生死鎖。

銀行家算法的基本思想是分配資源之前,判斷系統(tǒng)是否是安全的;若是,才分配。它是最具有代表性的避免死鎖的算法。

設(shè)進(jìn)程cusneed提出請(qǐng)求REQUEST[i],則銀行家算法按如下規(guī)則進(jìn)行判斷。

(1)如果REQUEST[cusneed][i]<=NEED[cusneed][i],則轉(zhuǎn)(2);否則,出錯(cuò)。

(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],則轉(zhuǎn)(3);否則,出錯(cuò)。

(3)系統(tǒng)試探分配資源,修改相關(guān)數(shù)據(jù):

AVAILABLE[i]-=REQUEST[cusneed][i];

ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];

NEED[cusneed][i]-=REQUEST[cusneed][i];

(4)系統(tǒng)執(zhí)行安全性檢查,如安全,則分配成立;否則試探險(xiǎn)性分配作廢,系統(tǒng)恢復(fù)原狀,進(jìn)程等待。

安全性檢查算法

(1)設(shè)置兩個(gè)工作向量Work=AVAILABLE;FINISH

(2)從進(jìn)程集合中找到一個(gè)滿足下述條件的進(jìn)程,

FINISH==false;

NEED<=Work;

如找到,執(zhí)行(3);否則,執(zhí)行(4)

(3)設(shè)進(jìn)程獲得資源,可順利執(zhí)行,直至完成,從而釋放資源。

Work=Work+ALLOCATION;

Finish=true;

goto2

(4)如所有的進(jìn)程Finish=true,則表示安全;否則系統(tǒng)不安全。

銀行家算法流程圖

算法(c語言實(shí)現(xiàn))

#include

#include

#include

#include /*用到了getch()*/

#define M 5 /*進(jìn)程數(shù)*/

#define N 3 /*資源數(shù)*/

#define FALSE 0

#define TRUE 1

/*M個(gè)進(jìn)程對(duì)N類資源最大資源需求量*/

int MAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};

/*系統(tǒng)可用資源數(shù)*/

int AVAILABLE[N]={10,5,7};

/*M個(gè)進(jìn)程已分配到的N類數(shù)量*/

int ALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

/*M個(gè)進(jìn)程已經(jīng)得到N類資源的資源量 */

int NEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};

/*M個(gè)進(jìn)程還需要N類資源的資源量*/

int Request[N]={0,0,0};

void main()

{

int i=0,j=0;

char flag;

void showdata();

void changdata(int);

void rstordata(int);

int chkerr(int);

showdata();

enter:{

printf("請(qǐng)輸入需申請(qǐng)資源的進(jìn)程號(hào)(從0到");

printf("%d",M-1);

printf("):");

scanf("%d",&i);

}

if(i<0||i>=M)

{

printf("輸入的進(jìn)程號(hào)不存在,重新輸入!\n");

goto enter;

}

err:{

printf("請(qǐng)輸入進(jìn)程");

printf("%d",i);

printf("申請(qǐng)的資源數(shù)\n");

printf("類別: A B C\n");

printf(" ");

for (j=0;j

{

scanf("%d",&Request[j]);

if(Request[j]>NEED[i][j])

{

printf("%d",i);

printf("號(hào)進(jìn)程");

printf("申請(qǐng)的資源數(shù) > 進(jìn)程");

printf("%d",i);

printf("還需要");

printf("%d",j);

printf("類資源的資源量!申請(qǐng)不合理,出錯(cuò)!請(qǐng)重新選擇!\n");

goto err;

}

else

{

if(Request[j]>AVAILABLE[j])

{

printf("進(jìn)程");

printf("%d",i);

printf("申請(qǐng)的資源數(shù)大于系統(tǒng)可用");

printf("%d",j);

printf("類資源的資源量!申請(qǐng)不合理,出錯(cuò)!請(qǐng)重新選擇!\n");

goto err;

}

}

}

}

changdata(i);

if(chkerr(i))

{

rstordata(i);

showdata();

}

else

showdata();

printf("\n");

printf("按'y'或'Y'鍵繼續(xù),否則退出\n");

flag=getch();

if (flag=='y'||flag=='Y')

{

goto enter;

}

else

{

exit(0);

}

}

/*顯示數(shù)組*/

void showdata()

{

int i,j;

printf("系統(tǒng)可用資源向量:\n");

printf("***Available***\n");

printf("資源類別: A B C\n");

printf("資源數(shù)目:");

for (j=0;j

{

printf("%d ",AVAILABLE[j]);

}

printf("\n");

printf("\n");

printf("各進(jìn)程還需要的資源量:\n");

printf("******Need******\n");

printf("資源類別: A B C\n");

for (i=0;i

{

printf(" ");

printf("%d",i);

printf("號(hào)進(jìn)程:");

for (j=0;j

{

printf(" %d ",NEED[i][j]);

}

printf("\n");

}

printf("\n");

printf("各進(jìn)程已經(jīng)得到的資源量: \n");

printf("***Allocation***\n");

printf("資源類別: A B C\n");

for (i=0;i

{

printf(" ");

printf("%d",i);

printf("號(hào)進(jìn)程:");

/*printf(":\n");*/

for (j=0;j

{

printf(" %d ",ALLOCATION[i][j]);

}

printf("\n");

}

printf("\n");

}

/*系統(tǒng)對(duì)進(jìn)程請(qǐng)求響應(yīng),資源向量改變*/

void changdata(int k)

{

int j;

for (j=0;j

{

AVAILABLE[j]=AVAILABLE[j]-Request[j];

ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];

NEED[k][j]=NEED[k][j]-Request[j];

}

}

/*資源向量改變*/

void rstordata(int k)

{

int j;

for (j=0;j

{

AVAILABLE[j]=AVAILABLE[j]+Request[j];

ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];

NEED[k][j]=NEED[k][j]+Request[j];

}

}

/*安全性檢查函數(shù)*/

int chkerr(int s)

{

int WORK,FINISH[M],temp[M];

int i,j,k=0;

for(i=0;i

for(j=0;j

{

WORK=AVAILABLE[j];

i=s;

while(i

{

if (Finish[i]==FALSE&&NEED[i][j]<=WORK)

{

WORK=WORK+ALLOCATION[i][j];

FINISH[i]=TRUE;

temp[k]=i;

k++;

i=0;

}

else

{

i++;

}

}

for(i=0;i

if(FINISH[i]==FALSE)

{

printf("\n");

printf("系統(tǒng)不安全! 本次資源申請(qǐng)不成功!\n");

printf("\n");

return 1;

}

}

printf("\n");

printf("經(jīng)安全性檢查,系統(tǒng)安全,本次分配成功。\n");

printf("\n");

printf(" 本次安全序列:\n");

printf("進(jìn)程依次為");

for(i=0;i

{

printf("%d",temp[i]);

printf(" -> ");

}

printf("\n");

return 0;

}

參考資料 >

生活家百科家居網(wǎng)