一、银行家算法概述
银行家算法(Banker's Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
二、银行家算法中的数据结构
为了实现银行家算法,在系统中必须设置这样四个数据结构:
1)Available向量:系统中可利用的资源数目
2)Max矩阵:每个进程对每种资源的最大需求
3)Allocation矩阵:每个进程已分配的各类资源的数目
4)Need矩阵:每个进程还需要的各类资源数
其中三个矩阵间存在下述关系:
Need[i,j] = Max[i,j] - allocation[i, j]
三、银行家算法自然语言描述
将银行家算法的逻辑转化为自然语言:
设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]
(4) 试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试分配作废,进程Pi等待。
四、代码实现
#include <bits/stdc++.h>
using namespace std;
vector<int> list1;
vector<int> list2;
vector<int> list_f;
vector<string> list3;
int count1=0,counts=0;
int u=0;
int s=0;
int j=0;
void caculNeed(int **max_List,int **allocation_List,int **need_List, int proceed_n, int source_n){
int count;
for(int i=0;i<proceed_n;i++){
for(int j=0;j<source_n;j++){
need_List[i][j]=max_List[i][j]-allocation_List[i][j];
}
}
}
int caculate_once(int **work_List,int available[],int **need_List,int **allocation_List,int **workANDallo,int flag[],int proceed_n, int source_n, int f){
while(counts < proceed_n-f){
for(int j=0;j<source_n;j++){
if(flag[u]==0 && work_List[s][j]>=need_List[u][j]){
count1++;
if(count1>source_n){
count1=0;
counts++;
for(int k=0;k<source_n;k++){
workANDallo[s][k]=work_List[s][k]+allocation_List[u][k];
if(s<proceed_n-1){
work_List[s+1][k]=workANDallo[s][k];
}
}
s++;
int temp=u;
u = (u + 1) % proceed_n;
return temp;
}
}else{
u = (u + 1) % proceed_n;
continue;
}
}
}
return -2;
}
bool secuT0(int **work_List,int **need_List,int **allocation_List,int available[],int **workANDallo,int flag[], int proceed_n, int source_n){
int count=proceed_n;
for(int i=0;i<source_n;i++){
work_List[0][i]=available[i];
}
while(count>0){
int p = caculate_once(work_List,available,need_List,allocation_List,workANDallo,flag, proceed_n, source_n,0);
if(p==-2){
list3.push_back("false");
return false;
}else{
list3.push_back("true");
flag[p]=1;
count--;
list1.push_back(p);
}
}
return true;
}
bool secuT(int req,int **work_List,int **need_List,int **allocation_List,int available[],int **workANDallo,int flag[], int proceed_n, int source_n){
int count=proceed_n-1;
for(int i=0;i<source_n;i++){
work_List[0][i]=available[i];
work_List[1][i]=available[i]+allocation_List[req-1][i];
}
for(int i=0;i<source_n;i++){
if(work_List[0][i]<need_List[req-1][i]){
return false;
}
}
flag[req-1]=1;
list2.push_back(req-1);
while(count>0){
int p = caculate_once(work_List,available,need_List,allocation_List,workANDallo,flag, proceed_n, source_n,1);
if(p==-2){
return false;
}else{
flag[p]=1;
count--;
list2.push_back(p);
}
}
return true;
}
void outAll(int **arr,int x,int source_n){
for(int i=0;i<source_n;i++)
cout<<" "<<arr[x][i]<<" ";
cout<<" | ";
}
void outAll_need_allo(int **arr,vector<int> list1,int source_n){
for(int i=0;i<source_n;i++)
cout<<" "<<arr[list1[j]][i]<<" ";
cout<<" | ";
}
void out_Process(int **work_List,int **need_List,int **allocation_List,int **workANDallo,vector<int> list_p,vector<string> list_f ,int proceed_n,int source_n){
cout<<" process "<<" work "<<" need "<<" allocation "<<" work+allocation "<< " finish "<<endl;
for(int i=0;i<proceed_n;i++){
cout<<" p"<<list_p[i]+1<<" | ";
outAll((int**)work_List,i,source_n);
outAll_need_allo((int**)need_List,list1,source_n);
outAll_need_allo((int**)allocation_List,list1,source_n);
outAll((int**)workANDallo,i,source_n);
cout<<" "<<list_f[i]<<" ";
cout<<" "<<endl;
j++;
}
}
int main(){
int proceed_n,source_n;
cout << "请输入进程数和资源类数:"<<endl;
cin >> proceed_n >> source_n;
int **work_List = new int *[proceed_n];
int **max_List = new int *[proceed_n];
int **allocation_List = new int *[proceed_n];
int **need_List = new int *[proceed_n];
int **workANDallo = new int *[proceed_n];
int *flag = new int[proceed_n];
int *available = new int[source_n];
int *availTotal = new int[source_n];
cout<<"请输入每一种资源的数量:"<<endl;
for(int i=0;i<source_n;i++){
cin>>availTotal[i];
}
cout << "请输入各进程最大资源数:"<<endl;
for (int i = 0; i < proceed_n; i++) {
max_List[i] = new int[source_n];
for (int j = 0; j < source_n; j++) {
cin>> max_List[i][j];
}
}
cout << "请输入各进程以已分配资源数:"<<endl;
for (int i = 0; i < proceed_n; i++) {
allocation_List[i] = new int[source_n];
for (int j = 0; j < source_n; j++) {
cin >> allocation_List[i][j];
}
}
int *all_allocation = new int[source_n];
for (int i = 0; i < source_n; i++) {
all_allocation[i] = 0;
for (int j = 0; j < proceed_n; j++) {
all_allocation[i] += allocation_List[j][i];
}
}
for (int i = 0; i < source_n; i++) {
available[i] = availTotal[i] - all_allocation[i];
}
for (int i = 0; i < proceed_n; i++) {
need_List[i] = new int[source_n];
workANDallo[i] = new int[source_n];
work_List[i] = new int[source_n];
flag[i] = 0;
for (int j = 0; j < source_n; j++) {
need_List[i][j] = 0;
workANDallo[i][j] = 0;
work_List[i][j] = 0;
}
}
caculNeed(max_List, allocation_List, need_List, proceed_n, source_n);
bool securityT0 = secuT0(work_List, need_List, allocation_List, available, workANDallo, flag, proceed_n, source_n);
cout<<"T0时刻资源分配情况表:"<<endl;
cout<<" process "<<" max "<<" allocation "<<" need "<<" available "<<endl;
int ava_count=0;
for(int i=0;i<proceed_n;i++){
cout<<" p"<<i+1<<" | ";
outAll((int**)max_List,i,source_n);
outAll((int**)allocation_List,i,source_n);
outAll((int**)need_List,i,source_n);
if(ava_count==0){
for(int s=0;s<source_n;s++)
cout<<" "<<available[s]<<" ";
}
ava_count++;
cout<<" "<<endl;
}
cout<<"______________________________________________________________________________________________________"<<endl;
cout<<endl;
cout<<endl;
if(securityT0){
cout<<"T0时刻序列表:"<<endl;
out_Process(work_List,need_List,allocation_List,workANDallo,list1,list3,proceed_n,source_n);
j=0;
cout<<endl;
cout<<"T0时刻安全性:利用安全性算法对T0时刻的资源分配情况进行分析,可知T0时刻存在一个安全序列:"<<endl;
for(auto &a:list1){
cout<<"p"<<a+1<<",";
}
cout<<endl<<"故系统是安全的!"<<endl;
}else {
out_Process(work_List,need_List,allocation_List,workANDallo,list1,list3,proceed_n,source_n);
cout<<"没有安全序列!故系统不安全!";
}
int requset[source_n],req;
cout<<endl;
cout<<"______________________________________________________________________________________________________"<<endl;
cout<<endl;
cout<<endl;
while(1){
cout<<"现(p1-p"<<proceed_n<<")发出请求(输入0退出):"<<endl;
cin>>req;
if(req==0){
break;
}
cout<<"发出的请求为:"<<endl;
for(int i=0;i<source_n;i++){
cin>>requset[i];
}
for(int i=0;i<proceed_n;i++){
flag[i]=0;
}
int count_need=0,count_available=0;
for(int i=0;i<source_n;i++){
if(requset[i]<=need_List[req-1][i])
{
count_need++;
if( requset[i]<=available[i]){
count_available++;
}
}
}
if(count_need==source_n && count_available==source_n){
cout<<"p"<<req<<"申请资源,系统按银行家算法进行检查:"<<endl;
for(int i=0;i<source_n;i++){
available[i]=available[i]-requset[i];
allocation_List[req-1][i]+=requset[i];
need_List[req-1][i]-=requset[i];
}
cout<<"① Requset"<<req<<"<="<<"need"<<req<<endl;
cout<<"② Requset"<<req<<"<="<<"available"<<req<<endl;
cout<<"检验通过!"<<endl;
}else if(count_need<source_n && count_available==source_n){
cout<<"① Requset"<<req<<">"<<"need"<<req<<endl;
cout<<"② Requset"<<req<<"<="<<"available"<<req<<endl;
cout<<"p"<<req<<"等待"<<endl;
break;
}else if(count_need==source_n && count_available<source_n){
cout<<"① Requset"<<req<<"<="<<"need"<<req<<endl;
cout<<"② Requset"<<req<<">"<<"available"<<req<<endl;
cout<<"p"<<req<<"等待"<<endl;
break;
}else{
cout<<"① Requset"<<req<<">"<<"need"<<req<<endl;
cout<<"② Requset"<<req<<">"<<"available"<<req<<endl;
cout<<"p"<<req<<"等待"<<endl;
break;
}
bool securityT = secuT(req,work_List, need_List, allocation_List, available, workANDallo, flag, proceed_n, source_n);
if(securityT){
cout<<"p"<<req<<"申请资源时的安全检查表:"<<endl;
out_Process(work_List,need_List,allocation_List,workANDallo,list2,list3,proceed_n,source_n);
j=0;
cout<<"p"<<req<<"请求资源是安全的,其安全序列为:"<<endl;
for(int &b:list2){
cout<<"p"<<b+1<<",";
}
}else {
for(int i=0;i<proceed_n;i++){
list_f.push_back(i);
}
cout<<"系统暂时先假设可为p"<<req<<"分配资源,并修改有关数据:"<<endl;
cout<<"为p"<<req<<"分配资源后的有关数据表:"<<endl;
cout<<" process "<<" allocation "<<" max "<<" available "<<endl;
int ava_count1=0;
for(int i=0;i<proceed_n;i++){
cout<<" p"<<i+1<<" | ";
outAll_need_allo((int**)allocation_List,list_f,source_n);
outAll_need_allo((int**)need_List,list_f,source_n);
if(ava_count1==0){
for(int s=0;s<source_n;s++)
cout<<" "<<available[s]<<" ";
}
ava_count1++;
cout<<" "<<endl;
j++;
}
cout<<endl;
cout<<"进行安全性检查:可用资源AVailable已不能满足任何进程的需要,故系统进入不安全状态,此时系统不可分配资源!"<<endl;
}
cout<<endl;
cout<<"______________________________________________________________________________________________________"<<endl;
}
for (int i = 0; i < proceed_n; i++) {
delete[] work_List[i];
delete[] allocation_List[i];
delete[] need_List[i];
delete[] workANDallo[i];
}
delete[] work_List;
delete[] allocation_List;
delete[] need_List;
delete[] workANDallo;
delete[] flag;
delete[] available;
return 0;
}
五、实验结果