操作系统 银行家算法

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


 




 

  

 

posted @ 2019-10-02 23:35  gidos  阅读(1851)  评论(0编辑  收藏  举报