银行家算法

 本文来自 http://blog.youkuaiyun.com/manymore13 


      在学操作系统这门课程的时候,里面有个银行家算法,第一次看见这个算法当时有傻眼,

 不知从何处入手,因为本人在这之前也没写过像这种稍微有点深度的程序(说来惭愧!!菜鸟)

 写一下博客也很好,一来可以练习打字,二来放在这里可以作为资料方便自己以后

 查阅,利于自己也利于大家嘛!                                     

                                 一起学习,一起努力!!!加油!!!!!


 银行家算法的数据结构:     

       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个,方能完成其任务。
  Need[i,j]=Max[i,j]-Allocation[i,j]


算法实现:

初始化

  由用户输入数据,分别对可利用资源向量矩阵AVAILABLE、最大需求矩阵MAX、分配矩阵ALLOCATION、需求矩阵NEED赋值。

银行家算法

  在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
  银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
  设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
  (1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
  (2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],则转(3);否则,出错。
  (3)系统试探分配资源,修改相关数据:
  AVAILABLE[i]-=REQUEST[cusneed][i];
  ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
  NEED[cusneed][i]-=REQUEST[cusneed][i];
  (4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

安全性检查算法

  (1)设置两个工作向量Work=AVAILABLE;FINISH
  (2)从进程集合中找到一个满足下述条件的进程,
  FINISH==false;
  NEED<=Work;
  如找到,执行(3);否则,执行(4)
  (3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
  Work+=ALLOCATION;
  Finish=true;
  GOTO 2
  (4)如所有的进程Finish= true,则表示安全;否则系统不安全。


 下面是我自己的程序基本是按照上面的思路写的


 我贴一下我程序里的几个函数,顺便说一下他们的作用。。。。。。

   1.void inputedate();

 

       程序一开始便要输入初始数据 等一下看程序你看一下就知道了

  
   2.void dealloc(int** a, int p);

  

      释放内存资源 我把一些数组(动态分配的)集中放在一起释放。。


   3.bool safe(int ProcessNum);

    

      银行家安全性算法 


   4.int  banker(int *request,int ProcessNum);

   

      银行家算法  他的流程  http://baike.baidu.com/view/93075.htm#4

 

   5.int  add(int array[],int element,int n); 

 

            array[] 这个用来存放安全序列



   6.void ShowInformation();

 

       显示当前数据状态: 最大需求矩阵  可利用资源向量  分配矩阵 需求矩阵


 



  下面是源码 :

      

/* 程序名:银行家算法
 * 环境: Visual C++ 6.0
 * 完成时间:2011-4-19 23:33
 */ 
#include <stdio.h>
#include <malloc.h> 
#include <stdlib.h>


void inputedate();
void dealloc(int** a, int p);
bool safe(int ProcessNum);
int  banker(int *request,int ProcessNum);
int  add(int array[],int element,int n);
void ShowInformation();

int  *available;
int  **max;
int  **allocation;
int  **need;
int  *request;
int  *work;
bool *finish;

int m;  //资源数
int n; //进程

int i;
int j;
int main(int argc, char* argv[])
{
	
   int SelectProces;
   int select;
   
	 inputedate();
	
	 while(true)
	 {
		 system("cls");
		 printf("\t┏━━━━━━━━━━━━━━━━┓\n");
		 printf("\t┃        1.请求资源              ┃\n");         
		 printf("\t┃        2.显示当前信息          ┃\n");
		 printf("\t┃        3.退出                  ┃\n");
		 printf("\t┗━━━━━━━━━━━━━━━━┛\n");
	 	 printf("输入您的选择:");
	 	 scanf("%d",&select);
	 	 
 	     switch(select)
         {
		     case 1:
			 {
			     printf("请选择哪个进程 P");
				 scanf("%d",&SelectProces);
				 if(SelectProces>=n||SelectProces<0)
				 {
					 continue;
				 }
				 if(banker(request,SelectProces))
				 {
					 if(!safe(SelectProces))
					 {
 						for(int i=0; i<m; i++)
						{
							available[i] += request[i];
							allocation[SelectProces][i] -= request[i];
							need[SelectProces][i]+=request[i];
						}  	
					 }
				 }
			 }
			 break;
			 case 2:
				 {
					 ShowInformation();
				 }
				 break;
			 case 3:
				 {
					 exit(1);
				 }
			 default:exit(1);
			
         }
		 system("pause");
 	 }
	 free(available);
	 dealloc(allocation,n); 
      dealloc(max,n);
	 dealloc(need,n);
	 
	return 0;
}

// 释放内存 二维 
void dealloc(int** a, int p)  
{
    int i;
    for (i = 0; i < p; i++)
    {
		free(a[i]);
    }
    free(a);
}

void inputedate()
{
	printf("请输入资源数:");
	scanf("%d",&m);
	printf("请输入进程数:");
	scanf("%d",&n);
	
	//可利用资源数 
	available = (int *)malloc(m*sizeof(int)); 
	 // 输入可利用资源数 
	for(i=0; i<m; i++)
	{
		printf("输入第%d类可利用资源数:",i);
		scanf("%d",&available[i]); 
	}
//	fflush(stdin);
	//最大需求量 
	max = (int **)malloc(n*sizeof(int *));
	for(i=0; i<n; i++)
	{
	    max[i] = (int *)malloc(m*sizeof(int)); 
	}
	// 输入各进程对各资源的最大需求量 
	for(i=0; i<n; i++)
	for(j=0; j<m; j++)
	{
		printf("进程P[%d]对资源%d的最大需求:",i,j);
		scanf("%d",&max[i][j]);
	}
	
	//已分配 
	allocation = (int **)malloc(n*sizeof(int *));
//	printf("This is test4\n"); 
	for(i=0; i<n; i++)
	{
	    allocation[i] = (int *)malloc(m*sizeof(int)); 
	} 
     // 输入已经分配数
	for(i=0; i<n; i++)
	for(j=0; j<m; j++)
	{
		printf("进程P[%d]已经分配资源%d量:",i,j);
		scanf("%d",&allocation[i][j]);
	}
	 //还需求 
	need = (int **)malloc(n*sizeof(int *)); 

	for(i=0; i<n; i++)
	{
	    need[i] = (int *)malloc(m*sizeof(int)); 
	}

	// 输入必要数据 
 
	// 求需求矩阵
	for(i=0; i<n; i++)
	{
	
     	for(j=0; j<m; j++)
	     {    
	     	
          	need[i][j] = max[i][j] - allocation[i][j];
			printf("%d ",need[i][j]);
	     }
	     printf("\n");
	}
	 
	 //request数组的大小
	 request = (int *)malloc(m * sizeof(int)); 
	 work = (int *)malloc(m * sizeof(int));
	 finish = (bool *)malloc(n* sizeof(bool));
}

// 银行家算法
int banker(int *request,int ProcessNum)
{
	
	//对每一个资源的请求量  resource为资源类数目 
	printf("输入请求的资源量:\n");
	for(int i=0; i<m; i++)
	{
		printf("请输入对资源R%d的请求量:",i);
		scanf("%d",&request[i]); 
	}
	// 开始检查
	for(i=0; i<m; i++)
	{
		if(request[i] > need[ProcessNum][i])
		{
		    printf("你请求资源R%d的资源数大于它所宣布的值",i);
		    return 0;	
		}
	}
     for(i=0; i<m; i++)
     {
     	if(request[i] > available[i])
		{
			printf("您尚无足够资源分配,P%d需等待......\n",ProcessNum);
			return 0;
		}
     }
     // 试分配
	for(i=0; i<m; i++)
	{
		available[i] -= request[i];
		allocation[ProcessNum][i] += request[i];
		need[ProcessNum][i]-=request[i];
	}
 	return 1;
}

bool safe(int ProcessNum)
{
	int count =0;
	int sub = 0;
	int flag =0;
	int *safeorder;
	int t = 0;
	safeorder = (int *)malloc(n*sizeof(int));
	for(i=0; i<n; i++) // 初始化数组
	{
		safeorder[i] = -1;
	}
	for(int i=0; i<m; i++)  // 初始化work 
	{
		work[i] = available[i];
	}
	for(int j=0; j<n; j++) // 初始化finish 
	{
		finish[j] = false;
	}

	while(true)     // n为进程数  n 趟  
	{
		if(sub==n)
		{
			sub=0;
		}
		if(finish[sub]==false)
		{
	
			flag = 0;
			for(int j =0; j<m; j++)  // m为资源数 
			{
				if(need[sub][j] <= work[j])  // 比较资源 
				{
					flag++;
				}
				else
				{
					break;
				}
			}
			if(m == flag)
			{
				for(i=0; i<m; i++)
				{
					work[i] += allocation[sub][i];
				}
				
				finish[sub] = true;
				if(finish[sub]==true)
				{
					add(safeorder,sub,n); //求出安全序列
					count++;
				
				}
			}
		}
		sub++;
		t++;
		if(n == count||t==n*n)
		{
          	break;
		}
	}

	for(i=0; i<n; i++)
	{
		if(finish[i]==false)
		{
			printf("\nSystem is not safe !\n");
			return false;
		}
	}

	printf("System is safe !\n"); 

	printf("存在一个安全序列: { ");

	for(i=0; i<n; i++)
	{
		if(i==n-1)
		{
            printf("P%d",safeorder[i]);
		}
		else
		{
			printf("P%d->",safeorder[i]);
		}
	}
	printf(" }\n");
	return true;
}

int add(int array[],int element,int n)  //数组处理
{
	int i;
	for(i=0; i<=n; i++)
	{
		if((array[i]!=element))
		{
		   if(-1==array[i])
		   {
   			 array[i] = element;
   			 break;
   		   }
		}
		else
		{
		   break;	
		} 
	}

	return 1;
}

void ShowInformation()
{
    printf("\n进程的最大需求(MAX)\n");
    for(i=0; i<n; i++)
	{
		printf("P%d :",i);
		for(j=0; j<m; j++)
		{
            printf("%d  ",max[i][j]);
		}
		printf("\n");
	}

	printf("\n进程已分配资源(Allocation)\n");

	for(i=0; i<n; i++)
	{
		printf("P%d :",i);
		for(j=0; j<m; j++)
		{
            printf("%d  ",allocation[i][j]);
		}
		printf("\n");
	}

	printf("\n进程需求(Need)\n");

	for(i=0; i<n; i++)
	{
		printf("P%d :",i);
		for(j=0; j<m; j++)
		{
            printf("%d  ",need[i][j]);
		}
		printf("\n");
	}

     printf("\n可利用资源(Available)\n");
     
	for(i=0; i<m; i++)
	{
         printf("%d  ",available[i]);
	}
}



  代码写的有点粗糙,此代码在求安全序列的时候只能求出一种,求多种的不会写呀!

有大牛看到这代码有哪些不好的请指出来,我也好改正改正。。。。

第一次在csdn里发东西,请多指教。。。

银行家算法下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值