操作系统养成计划之篇二:死锁实战篇——银行家算法

来源:互联网 发布:java可逆的加密算法 编辑:程序博客网 时间:2024/06/04 23:02

banker's algorothm

银行家算法是针对避免死锁问题的经典算法

其算法以银行借贷为基础,判断并且保证系统的安全运行

介绍银行家算法需要先介绍三个概念:

1:安全序列:指一个进程序列{123... n},对于每一个进程来说,都有他之后所需的资源量不超过系统当前剩余的资源量与该进程当前所占据资源量之和。

2、安全状态

系统中所有进程可以构成一个安全序列,则可以称该系统处于安全状态,安全状态是一定没有死锁发生的。

3、不安全状态

系统中不存在一个安全序列。不安全状态不一定发生死锁。

 

算法描述(数据结构)

系统可利用资源向量:available

定义一个含有m个向量的数组,表示系统可以利用的各类(m类)资源的总数,比如available[2]=10;表示第二类资源的总数为10个;

最大需求矩阵MAX

这是一个n*m的一个数组,表示系统中n个进程对于各类资源的最大需求,如MAX[1,2]=10;表示下标为1的进程需要第二类资源10个;

分配矩阵allocation

这也是一个n*m的矩阵,表示系统中各个进程已经分配的各类资源;如allocation[1,2]=5;表示下标为1的进程已经分配第二类资源5个。

需求矩阵need

同样,这个也是一个n*m的矩阵,表示各个进程目前尚需各类资源的数目,比如need[1,2]=3;

表示下标为1的进程需要第二类资源3个。Need[n,m]=MAX[n,m]-allocation[n,m];

 

安全算法的检测

举个栗子(反正不是板个栗子)

系统中存在A,B,C 3个进程,内存资源最大需求分别为70,60,50;内存资源总量为100,若当前分配资源分别是40,20,10;则在初始时刻各资源表示如下表:

 

Max

Allocation

Need

Residue

A

70

30

30

30

B

60

20

40

 

C

50

10

10

 

可见安全序列存在,为A->B->C或者为A->C->B

若这个时候C资源请求分配10个资源,系统会假定分配给C,然后检测系统安全性

 

Max

Allocation

Need

Residue

A

70

30

30

20

B

60

20

40

 

C

50

20

30

 

则当前剩余资源不能满足任何一个进程,不存在安全序列,则系统丑拒C的请求

 

以下是源码部分,源码主体架构来自于百度百科,但经过验证发现,该源码存在严重bug,即当进程获得所有资源之后,并不会释放该资源,以下源码已修正该bug,(哎,百度啊)

以下部分均为代码,开发环境VS2008,开发语言C。

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
//*************** Initialize  variable   start **********************//
#define process 5   //define process number
#define resource 3    //define resource category number
#define false 0
#define true 1
#define runing 0   //process execution status
#define over 1
int max[process][resource]={{8,5,4},{1,4,2},{7,0,3},{2,2,2},{4,4,3}};
int available[resource]={12,6,7};
int allocation[process][resource]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
int need[process][resource]={{8,5,4},{1,4,2},{7,0,3},{2,2,2},{4,4,3}};
int request[resource]={0,0,0};
//*************** Initialize  variable   end **********************//
/*  Declare functions  we defineded start   */
void showdata();
void changdata(int);
void rstordata(int);
void process_over();
int chkerr();
/*  Declare functions  we defineded end   */
void main()        //main function
{
 int i=0,j=0;
 char flag;
 showdata();//show message about Initialzed
enter:
 {
  printf("请输入需申请资源的进程号(从0到");
  printf("%d",process-1);
  printf("):");
  scanf("%d",&i);
 }
 if(i<0||i>=process)
 {
  printf("输入的进程号不存在,重新输入!\n");
  goto enter;
 }
err:
 {
  printf("请输入进程");
  printf("%d",i);
  printf("申请的资源数\n");
  printf("类别:ABC\n");
  printf("");
  for(j=0;j<resource;j++)
  {
   scanf("%d",&request[j]);
   if(request[j]>need[i][j])
   {
    printf("%d",i);
    printf("号进程");
    printf("申请的资源数>进程");
    printf("%d",i);
    printf("还需要");
    printf("%d",j);
    printf("类资源的资源量!申请不合理,出错!请重新选择!\n");
    goto err;
   }
   else
   {
    if(request[j]>available[j])
    {
     printf("进程");
     printf("%d",i);
     printf("申请的资源数大于系统可用");
     printf("%d",j);
     printf("类资源的资源量!申请不合理,出错!请重新选择!\n");
     goto err;
    }
   }
  }
 }
 changdata(i);
 if(chkerr())
 {
  rstordata(i);
  showdata();
 }
 else
 {
  process_over(i);
  showdata();
 }
 printf("\n");
 printf("按'y'或'Y'键继续,否则退出\n");
 flag=getch();
 if(flag=='y'||flag=='Y')
 {
  goto enter;
 }
 else
 {
  exit(0);
 }
}
/*    Display status of resource used:showdata function start */
void showdata()
{
 int i,j;
 printf("系统可用资源向量:\n");
 printf("***Available***\n");
 printf("资源类别:A B C\n");
 printf("资源数目:");
 for(j=0;j<resource;j++)
 {
  printf("%d  ",available[j]);
 }
 printf("\n");
 printf("\n");
 printf("各进程还需要的资源量:\n");
 printf("******Need******\n");
 printf("资源类别:A B C\n");
 for(i=0;i<process;i++)
 {
  printf("");
  printf("%d",i);
  printf("号进程:");
  for(j=0;j<resource;j++)
  {
   printf("%d  ",need[i][j]);
  }
  printf("\n");
 }
 printf("\n");
 printf("各进程已经得到的资源量:\n");
 printf("***Allocation***\n");
 printf("资源类别:A B C\n");
 for(i=0;i<process;i++)
 {
  printf("");
  printf("%d",i);
  printf("号进程:");
  for(j=0;j<resource;j++)
  {
   printf("%d  ",allocation[i][j]);
  }
  printf("\n");
 }
 printf("\n");
}
/*    Display status of resource used:showdata function start */
/*Change variable value start*/
void changdata(int k)
{
 int j;
 for(j=0;j<resource;j++)
 {
  available[j]=available[j]-request[j];
  allocation[k][j]=allocation[k][j]+request[j];
  need[k][j]=need[k][j]-request[j];
 }
}
/*Change variable value end*/
/*restord variable value function start */
void rstordata(int k)
{
 int j;
 for(j=0;j<resource;j++)
 {
  available[j]=available[j]+request[j];
  allocation[k][j]=allocation[k][j]-request[j];
  need[k][j]=need[k][j]+request[j];
 }
}
/*restord variable value function end */
/*safety inspectionn function start*/
int chkerr()
{
 int WORK[resource],FINISH[process],temp[process];//temp[]:process execution sequence
 int i,j,m,k=0,count;
 for(i=0;i<process;i++)
  FINISH[i]=false;
 for(j=0;j<resource;j++)
  WORK[j]=available[j];
 for(i=0;i<process;i++)
 {
  count=0;
  for(j=0;j<resource;j++)
   if(FINISH[i]==false&&need[i][j]<=WORK[j])
    count++;
  if(count==resource)//All process:need<=work
  {
   for(m=0;m<resource;m++)
    WORK[m]=WORK[m]+allocation[i][m];
   FINISH[i]=true;
   temp[k]=i;
   k++;
   i=-1;
  }
 }
 for(i=0;i<process;i++)
  if(FINISH[i]==false)
  {
   printf("系统不安全!!!本次资源申请不成功!!!\n");
   return 1;
  }
  printf("\n");
  printf("经安全性检查,系统安全,本次分配成功。\n");
  printf("\n");
  printf("本次安全序列:");
  for(i=0;i<process;i++)//display safety execution sequence
  {
   printf("进程");
   printf("%d",temp[i]);
   if(i<process-1)
    printf("->");
  }
  printf("\n");
  return 0;
}
/*safety inspectionn function end*/
/*=====Release resource when process over start===== */

void process_over(int k)
{
 int j;
 int flag=over;
  for(j=0;j<resource;j++)
  { 
   if(need[k][j]!=0)
    flag=runing;
  }
  if(flag==over)
  {
   printf("进程");
   printf("%d",k);
   printf("已获得所有资源,执行完毕,释放所占用资源\n");
   for(j=0;j<resource;j++)
   {
    available[j]=available[j]+allocation[k][j];
    need[k][j]=allocation[k][j];
    allocation[k][j]=0;
  }
 }
};
/*=====Release resource when process over end===== */

以下为该代码执行后效果截图:
以上为对于银行家算法学习整理心得,若有错误,望指正!
Thanks for your reading!

原创粉丝点击