银行家算法中的数据结构
(1)可利用资源向量Available.这是一个含有m个元素的数组,其中的每一个元素代表一类可利用资源的数目,其初始值是系统中所配置的该类型全部可用资源的数目,其数值随该类资源的分配和回而动态的改变.如果Available[j]=k,则表示系统中现有Rj类资源k个.
(2)最大需求矩阵Max.这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求.Max[i,j]=k,则表示进程i需要Rj类资源的最大数目为k.
(3)分配矩阵Allocation.这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一个进程的资源数.如果Allocation[i,j]=k,则表示进程i当前已分得Rj类资源的数目为k.
(4)需求矩阵Need.这也是一个n*m的矩阵,用以表示每个进程尚需的各类资源数.如果Need[i,j]=k,则表示进程i还需要Rj类资源k个方能完成其任务.
银行家算法
设Request i(i是下标) 是进程Pi的请求向量,如果Request i[j]=k,表示进程pi需要K个Rj类型的资源.当pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Request i[j] <= Need[i,j],便转向步骤(2);否则认为出错,因为它所需的资源数已超过它所宣布的最大值.
(2)如果Request i[j] <= Available[j],便转向步骤(3);否则,表示尚无足够的资源,p i须等待.
(3)系统试探的把资源分配给进程p i,并修改下面数据结构中的数值:
Available[j] = Available[j] - Request i[j];
Allocation[i,j] = Allocation[i,j] + Request i[j];
Need[i,j] = Need[i,j] - Request i[j];
(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态.若安全,才正式将资源分配给进程p i,已完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程p i等待.
安全性算法
系统执行的安全性算法可描述如下:
(1)设置两个向量:1.工作向量work,他表示系统可提供给进程继续运行所需要的各类资源数目,它含有m个元素,在执行安全算法开始时,work = Available; 2.finish:它表示系统有足够的资源分配给进程,使之运行完成.开始时先做finish[i] = false;当有足够资源分配给进程时,再令finish[i] = true;
(2)从进程集合中找到一个能满足下述条件的进程:
1.finish[i] = false;
2.Need[i,j] <= work[j];
若找到,执行步骤(3),否则,执行步骤(4)
(3)当进程p i获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
work[j] = work[j] + Allocation[i,j];
finish[i] = true;
go to step 2
(4)如果所有进程的finish[i] = true都满足,则表示系统处于安全状态;否则,系统处于不安全状态
代码实现:
为了模仿计算机进程,编者使用随机值进行初始化
int main() { int progress ; int resource; bool flag = false; //最后判断安全序列的标志 bool flag1 = false; printf("请输入进程个数:"); int test = scanf("%d",&progress); //行数 while(test == 0)//输入异常机制 { printf("输入有误,请重试!\n"); fflush(stdin); //清除缓存 printf("请输入进程个数:"); test = scanf("%d",&progress); } printf("请输入资源个数:"); int test1 = scanf("%d",&resource); //列数 while(test1 == 0)//输入异常机制 { printf("输入有误,请重试!\n"); fflush(stdin); //清除缓存 printf("请输入资源个数:"); test1 = scanf("%d",&resource); } int **Need = NULL; int **Allocation = NULL; int **Request = NULL; Need = OpenSpace2(Need,progress,resource); Allocation = OpenSpace2(Allocation,progress,resource); Request = OpenSpace2(Request,progress,resource); int *Available = (int *)malloc(sizeof(int)*resource); assert(Available != NULL); int *arr = (int*)calloc(progress,sizeof(int)); //保存安全序列 assert(arr != NULL); Init(Need,Allocation,Request,Available,progress,resource); Show(Need,Allocation,Request,Available,progress,resource); flag1 = Safe(Need,Allocation,Request,Available,progress,resource,arr); if(!flag1) { Delete(Need,Allocation,Request,Available,progress,arr); return 0; } flag = Bank(Need,Allocation,Request,Available,progress,resource,arr); if(flag) { printf("安全序列为:\n"); for(int i =0; i< progress;i++) { printf("P%d ",arr[i]); } printf("\n"); } //Show(Need,Allocation,Request,Available,progress,resource); Delete(Need,Allocation,Request,Available,progress,arr); return 0; }
bool Bank(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource,int *arr) { assert(Need != NULL && Allocation != NULL && Request != NULL); //bool *finish =(bool*)malloc(sizeof(bool)*progress); bool flag = false; //assert(finish != NULL); int k; printf("请输入请求向量进程号(从0开始):"); int test = scanf("%d",&k); while(test == 0 || k >=progress || k < 0 )//输入异常机制 { printf("输入有误,请重试!\n"); fflush(stdin); //清除缓存 printf("请输入请求向量进程号(从0开始):"); test = scanf("%d",&k); } printf("请输入请求向量(回车分隔):\n"); for(int i = 0; i < resource ;i++) { int test1 = scanf("%d",&Request[k][i]); if(test1 == 0) //输入异常机制 { fflush(stdin); //清除缓存 printf("输入有误,请重新输入!\n"); i--; } if(Request[k][i] > Need[k][i] ) { printf("输入有误,请重新输入!\n"); i--; } } int j = 0; for( j = 0; j < resource;j++) { if(Request[k][j] > Available[j]) { printf("尚无足够资源,P%d需等待\n",k); return false; } flag = true; } if(flag) { for( j = 0;j < resource;j++) { Available[j] -=Request[k][j]; Allocation[k][j] += Request[k][j]; Need[k][j] -= Request[k][j]; } if(!Safe(Need,Allocation,Request,Available,progress,resource,arr))//如果不安全 { flag = false; for( j = 0; j < resource;j++)//恢复资源 { Available[j] +=Request[k][j]; Allocation[k][j] -= Request[k][j]; Need[k][j] += Request[k][j]; } } } if(flag == false) { printf("系统处于不安全状态\n"); return false; } else { printf("系统处于安全状态\n"); return true; } }
bool Safe(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource,int *arr) { assert(Need != NULL && Allocation != NULL && Available != NULL); int k = 0; //arr的下标 int *Work = (int *)malloc(sizeof(int)*resource); assert(Work != NULL); for(int i = 0; i< resource;i++) { Work[i] = Available[i]; } bool *finish =(bool*)malloc(sizeof(bool)*progress); assert(finish != NULL); for(int i = 0; i< progress;i++) { finish[i] = false; } //Show(Need,Allocation,Request,Available,progress,resource); for(int i = 0;i < progress; i++) { if(!finish[i]) { int j; for( j = 0; j < resource;j++) { if(Need[i][j] > Work[j]) { break; //判断下一个进程是否安全 } if(j+1 == resource) //即Need中[i]向量,所有的值都小于Work向量的值 j为下标,resource为资源数 { finish[i] = true; arr[k++] = i; for(j = 0;j < resource;j++) { Work[j] += Allocation[i][j]; } i = -1; //重新开始扫描 } } } } for(int i = 0; i < progress; i++) { if(!finish[i]) { free(Work); free(finish); printf("此时处于不安全的状态\n"); return false; } } free(Work); free(finish); printf("此时处于安全的状态\n"); return true; }
void Init(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource)//初始化 { assert(Need != NULL && Allocation != NULL); srand((unsigned)time( NULL ) ); for(int i = 0; i < progress;i++) { for(int j = 0 ;j< resource; j++) { Need[i][j] = rand()%8+0; Allocation[i][j] = rand()%7+0; Request[i][j] = 0; } } for(int i = 0; i < resource;i++) { Available[i] = rand()%10+5; } }
void Show(int **Need,int **Allocation,int **Request ,int * Available,int progress,int resource) { assert(Need != NULL && Allocation != NULL); printf("需求矩阵:\t\t分配矩阵:\t\t需求矩阵:\n"); for(int i = 0; i < progress;i++) { for(int j = 0 ;j< resource; j++) { printf("%d ",Need[i][j]); } printf("\t\t\t"); for(int j = 0 ;j< resource; j++) { printf("%d ",Allocation[i][j]); } printf("\t\t\t"); for(int j = 0 ;j< resource; j++) { printf("%d ",Request[i][j]); } printf("\n"); } printf("可利用资源向量:\n"); for(int i = 0; i < resource;i++) { printf("%d ",Available[i]); } printf("\n"); }
依次拼接即可使用,如果没有<vdl.h>的插件,直接屏蔽即可.
如果在使用中发现问题,望指出.