是一个避免死锁(Deadlock)的著名算法,它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
1).银行家算法中的数据结构
(1).可利用资源向量Available
(2).最大需求矩阵Max
(3).分配矩阵Allocation
(4).需求矩阵Need
2).银行家算法
Request请求向量,
(1).如果Request[i] <= Need[i][j]转下步,否则它所需要的资源数已超过它所需要的最大值
(2).如果Request[i] <= Available[i][j]转下步,否则尚无足够资源,进程需等待
(3).系统试分配给进程p,并修改Available,Allocation和Need
Available[j] -= Request[j]
Allocation[i][j] += Request[j]
Need[i][j] -= Request[j]
(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态.若安全,才正式分配;否则恢复原来的分配状态,让该进程等待
3).安全性算法
(1).设置两个向量,工作向量Work,在执行安全性算法开始时 Work=Available;Finish:表示有足够的资源分配给进程,使之运行完成,Finish[i]=false;当有足够资源分配给进程时,再另Finish[i]=false
(2).从进程集合中找到一个满足该条件的进程:
Finish[i]=false
Need[i][j] <= Work[j]
(3).当进程获得资源后,可顺利执行,并修改Work向量和Finsh向量
Work[i] += Allocation[i][j]
Finish[i]=true
(4).如果所有进程的Finish[i]=true说明系统处于安全状态,否则系统处于不安全状态.
#include<stdio.h> #include <stdlib.h> #include <string> typedef struct process * proc; typedef struct system * sys; static int cur_resource = 3; struct process{ int process_id; int resource_num; int * Max; int * Allocation; int * Need; int * request; int Finish; int flag; }; struct system{ int resource_num; int * Available; }; void scanf_num(int * li,int n){ int i; for(i=0;i<n;i++){ printf("输入第%d类资源数\n",i+1); scanf("%d",li); li ++; } } sys create_system(){ system("cls"); sys new_sys = (sys)malloc(sizeof(struct system)); new_sys->resource_num = cur_resource; new_sys->Available = (int * )malloc((new_sys->resource_num) * sizeof(int)); printf("输入系统拥有资源\n"); scanf_num(new_sys->Available,new_sys->resource_num); return new_sys; } proc create_process(){ system("cls"); int i; proc new_process = (proc)malloc(sizeof(struct process)); printf("输入进程编号\n"); scanf("%d",&new_process->process_id); new_process->resource_num = cur_resource; new_process->Max = (int * )malloc((new_process->resource_num) * sizeof(int)); printf("输入进程可执行资源数量\n"); scanf_num(new_process->Max,new_process->resource_num); new_process->Allocation = (int * )malloc((new_process->resource_num) * sizeof(int)); printf("输入进程拥有资源数量\n"); scanf_num(new_process->Allocation,new_process->resource_num); new_process->Need = (int * )malloc((new_process->resource_num) * sizeof(int)); for(i=0;i<new_process->resource_num;i++){ new_process->Need[i] = new_process->Max[i] - new_process->Allocation[i]; } new_process->Finish = 0; new_process->flag = 0; new_process->request = (int * )malloc((new_process->resource_num) * sizeof(int)); return new_process; } sys deep_copy_system(sys d1){ int i; sys new_sys = (sys)malloc(sizeof(struct system)); new_sys->resource_num = d1->resource_num; new_sys->Available = (int * )malloc((new_sys->resource_num) * sizeof(int)); for(i=0;i<d1->resource_num;i++){ new_sys->Available[i] = d1->Available[i]; } return new_sys; } proc deep_copy_process(proc p1){ int i; proc new_process = (proc)malloc(sizeof(struct process)); new_process->process_id = p1->process_id; new_process->resource_num = p1->resource_num; new_process->Max = (int * )malloc((new_process->resource_num) * sizeof(int)); for(i=0;i<p1->resource_num;i++){ new_process->Max[i] = p1->Max[i]; } new_process->Allocation = (int * )malloc((new_process->resource_num) * sizeof(int)); for(i=0;i<p1->resource_num;i++){ new_process->Allocation[i] = p1->Allocation[i]; } new_process->Need = (int * )malloc((new_process->resource_num) * sizeof(int)); for(i=0;i<new_process->resource_num;i++){ new_process->Need[i] = new_process->Max[i] - new_process->Allocation[i]; } new_process->Finish = p1->Finish; new_process->flag = p1->flag; new_process->request = (int * )malloc((new_process->resource_num) * sizeof(int)); for(i=0;i<p1->resource_num;i++){ new_process->request[i] = p1->request[i]; } return new_process; } void show_process_and_system(sys system,proc proc_list[],int process_num){ int i,j,k; printf("|----------------------|--------------------------|--------------------------|--------------------------|--------------------------|\n"); printf("| 进程名 | MAX | Allocation | Need | available |\n"); for(j=0;j<process_num;j++) { printf(" \t P%d \t ",proc_list[j]->process_id); for(k=0;k<3;k++){ printf(" "); if(k==0){ for(i=0;i<proc_list[j]->resource_num;i++){ printf(" %d ",proc_list[j]->Max[i]); } } if(k==1){ for(i=0;i<proc_list[j]->resource_num;i++){ printf(" %d ",proc_list[j]->Allocation[i]); } } if(k==2){ for(i=0;i<proc_list[j]->resource_num;i++){ printf(" %d ",proc_list[j]->Need[i]); } } } printf("\n"); } printf(" "); for(k=0;k<system->resource_num;k++){ printf(" %d ",system->Available[k]); } printf("\n"); printf("|----------------------|--------------------------|--------------------------|--------------------------|--------------------------|\n"); } void menu(){ printf("1:输入编号 进行请求\n"); printf("2: \n"); printf("0:退出\n"); } proc serach_process(proc proc_list[255],int process_num,int proceess_id){ int i; for(i=0;i<process_num;i++){ if(proc_list[i]->process_id==proceess_id){ return proc_list[i]; } } return NULL; } bool intchkerr(proc p_test,proc p_test_list[255],int p_num,sys s_test){ int i,j; int secure_array[p_num]; int secure_count=0; int flag=1; int all_finish=0; int first_flag=0; while(1){ for(i=0;i<p_num;i++){ if(p_test_list[i]->Finish==0){ flag =1; for(j=0;j<p_test_list[i]->resource_num;j++){ if(p_test_list[i]->Need[j] <= s_test->Available[j]){ flag=1; first_flag=1; }else{ flag=0; first_flag=0; break; } } if(flag){ for(j=0;j<s_test->resource_num;j++){ s_test->Available[j] = s_test->Available[j] + p_test_list[i]->Allocation[j]; } secure_array[secure_count] = p_test_list[i]->process_id; secure_count = secure_count + 1; p_test_list[i]->Finish = 1; } } } //printf("执行了"); for(i=0;i<p_num;i++){ if(p_test_list[i]->Finish==1){ all_finish = 1; }else{ all_finish = 0; break; } } if(all_finish){ printf("安全序列为"); for(i=0;i<p_num;i++){ printf("P%d -->",secure_array[i]); } printf("\n"); return 1; } if(all_finish==0 && first_flag==0){ printf("无安全序列"); printf("\n"); return 0; } } } bool Banker(proc p1,proc proc_list[255],int process_num,sys system_mod){ int i; sys system_test; proc process_test; proc temp; proc temp2; proc proc_list_test[255]; for(i=0;i<p1->resource_num;i++){ if(p1->request[i]>p1->Need[i]){ printf("出错 所需要的资源超过所宣布的最大值\n"); return 0; } } for(i=0;i<p1->resource_num;i++){ if(p1->request[i]>system_mod->Available[i]){ printf("出错 尚无足够资源\n"); return 0; } } //printf("开始拷贝"); system_test = deep_copy_system(system_mod); process_test = deep_copy_process(p1); for(i=0;i<process_num;i++){ temp2 = proc_list[i]; temp = deep_copy_process(temp2); proc_list_test[i] = temp; } for(i=0;i<process_test->resource_num;i++){ system_test->Available[i] = system_test->Available[i] - process_test->request[i]; process_test->Allocation[i] = process_test->Allocation[i] + process_test->request[i]; process_test->Need[i] = process_test->Need[i] - process_test->request[i]; } for(i=0;i<process_num;i++){ if(proc_list_test[i]->process_id==process_test->process_id){ proc_list_test[i] = process_test; } } //printf("进行安全性检查"); if(intchkerr(process_test,proc_list_test,process_num,system_test)){ return 1; }else{ return 0; } } void menu_1(sys system_mod,proc proc_list[255],int process_num){ system("cls"); show_process_and_system(system_mod,proc_list,process_num); int process_id_in; proc user_serach_proc=NULL; int i; printf("输入进程编号\n"); scanf("%d",&process_id_in); user_serach_proc = serach_process(proc_list,process_num,process_id_in); if(user_serach_proc){ printf("输入需要的资源\n"); scanf_num(user_serach_proc->request,user_serach_proc->resource_num); if(Banker(user_serach_proc,proc_list,process_num,system_mod)){ printf("安全!!! 本次分配成功!!!\n"); }else{ printf("不安全!!!本次资源申请不成功!!!\n"); } }else{ printf("无此进程\n"); } system("pause"); } int main(){ int process_num; int i; int user_input; proc proc_list[255]; printf("输入资源个数\n"); scanf("%d",&cur_resource); sys system_mod = create_system(); proc proc1 = NULL; printf("输入进程数量\n"); scanf("%d",&process_num); for(i=0;i<process_num;i++){ proc1 = create_process(); proc_list[i] = proc1; } while(1){ system("cls"); show_process_and_system(system_mod,proc_list,process_num); menu(); scanf("%d",&user_input); if(user_input==1){ menu_1(system_mod,proc_list,process_num); } else if(user_input==0){ break; }else{ continue; } } return 0; }