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