是一個避免死鎖(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; }