C語言實現銀行家算法


//銀行家算法
/**
* 作者:老謝
* 最后修改日期:2006,4,21
* Email:do_while@sohu.com
* 功能:銀行家算法實現
**/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define M 5 /*進程數*/
#define N 3 /*資源數*/

/**
* TC中用到
#define true 1
#define false 0
typedef int bool
**/
//系統可用資源向量
int Available[N] = {3,3,2};
//最大需求向量
int Max[M][N] = {
         {7,5,3},
         {3,2,2},
         {9,0,2},
         {2,2,2},
         {4,3,3},
  };
//資源分配向量
int Allocation[M][N] = {
   {0,1,0},
   {2,0,0},
   {3,0,2},
   {2,1,1},
   {0,0,2},
   };
//需求向量
int Need[M][N] = {
  {7,4,3},
  {1,2,2},
  {6,0,0},
  {0,1,1},
  {4,3,1},
  };

//比較兩個一維數組
//判斷 a >= b ?
bool compare(int *a,int *b,int n)
{
 int i=0;
 for(i = 0;i < n;i++)
 {
  if(a[i] < b[i])
  {
   return false;
  }
 } 

 return true;

}

//一維數組加法
//a = a + b
void add(int *a,int *b,int n)
{
 int i = 0;
 for(i = 0;i < n;i++)
 {
  a[i] += b[i];
 }
}

//一維數組減法
//a = a - b
void subtract(int *a,int *b,int n)
{
 int i = 0;
 for(i = 0;i < n;i++)
 {
  a[i] -= b[i];
 }
}

//將數組b的值賦給a,n為數組的大小
void assign(int *a,int *b,int n)
{
 int i = 0;
 for(i = 0;i < n;i++)
 {
  a[i] = b[i];
 }
}

//判斷是否是安全狀態
//av 可用資源矩陣
//sl 記錄安全路徑
bool safe(int *sl)
{
 int i;
 int count = 0; /*記錄finish[i] = true 的個數*/
 int n = 0;
 int work[N];
 bool finish[M];
 //work = av;
 assign(work,Available,N);
 //初始化標記 finish
 for(i = 0;i < M;i++)
 {
  finish[i] = false;
 }
 
 //n為進程的個數
 //循環最多執行n次
 n = M;
 while(n--)
 {
     for(i = 0;i < M;i++)
     {
      //判斷是否安全
      if(count >= M)
      {
       //全部進程都可安全執行(finish = true)
       return true;
      }
   
      //判斷能否滿足進程i的要求
      //work >= Need[i] ?
      if(finish[i] == false && compare(work,Need[i],N))
      {
       //分配,待進程完成后再釋放
       add(work,Allocation[i],N);
       finish[i] = true;     

 
       //記錄安全路徑
       sl[count] = i;
       //能滿足的進程數+1       
       count++;
      }
     }
 }
 if(count >= M)
 {
  return true;
 }
 else
 {
  return false;
 } 
}

//請求分配
//pid進程,r請求向量,n資源個數
bool request(int pid,int * r,int n)
{
 int i;
 //記錄安全路徑
 int sl[5]; 
 if(compare(Need[pid],r,n) == true &&
        compare(Availavle,r,n))
 {
  //嘗試分配資源
  subtract(Available,r,N);
  add(Allocation[pid],r,N);
  subtract(Need[pid],r,N);  

  //判斷是否是安全狀態
  if(safe(sl))
  {
   //打印安全路徑
   printf("安全路徑:/n/t");  
   for(i = 0;i < M;i++)
   {
    printf("p%d ",sl[i]);
   }
   printf("/n");
   //可以分配
   return true;
  }
  else
  {
   //不分配
   //恢復到分配前的狀態
   add(Available,r,N);
   subtract(Allocation[pid],r,N);
   add(Need[pid],r,N);

   return false;
  }
 }
 else
 {
  //error
  return false;
 }
}

//打印一維數組
void print(int *a,int n)
{
 int i;
 for(i = 0;i < n;i++)
 {
  printf("%4d",a[i]);
 }
 printf("/n");
}

//提示信息
char help()
{
 printf("-----操作提示-----/n");
 printf("A--自動隨機申請資源/n");
 printf("S--手動輸入申請資源/n");
 return getch();
}

//顯示系統信息
void init()
{
 int i;
 printf("該系統共有進程5個,/n其對資源的需求和分配情況分別是:/n");
 for(i = 0;i < M;i++)
 {
  printf("/t進程%d資源最大需求:",i);
  print(Max[i],N);
 }
 printf("/n");
 for(i = 0;i < M;i++)
 {
  printf("/t進程%d已經分配資源:",i);
  print(Allocation[i],N);
 }

 printf("系統可用資源數量:/n/t");
 print(Available,N);
}

//輸入
void input(int *r,int n,int *id)
{
 char ch;
 printf("請輸入進程的id(0 ~ 4):/n");
 ch = getche();
 *id = ch - 0x30;

 printf("/n請輸入對0類資源的申請數量(int):/n");
 ch = getche();
 r[0] = ch - 0x30;
 
 printf("/n請輸入對1類資源的申請數量(int):/n");
 ch = getche();
 r[1] = ch - 0x30;
 
 printf("/n請輸入對2類資源的申請數量(int):/n");
 ch = getche();
 r[2] = ch - 0x30;

 printf("/n您輸入的是:Request[%d](%d,%d,%d)/n",*id,r[0],r[1],r

[2]);
}

//檢查輸入
bool check(int id,int r1,int r2,int r3)
{
 if(id > 4 || id < 0 || r1 < 0 || r2 < 0 || r3 < 0)
 {
  return false;
 }
 else
 {
  return true;
 }
}

int main()
{
 //進程id
 int id;
 //控制字符
 char control;
 //資源請求向量
 int r[3];
 //顯示開始信息
 init();
 //隨機數初始化
 srand(NULL);
 //主控過程
 while(1)
 {
  //提示
  control = help();
  if(control == 'a' || control == 'A')
  {
   //隨機申請資源
   id = rand()%5;
   r[0] = rand()%5;
   r[1] = rand()%5;
   r[2] = rand()%5;
   //顯示申請信息
   printf("/tRequest[%d](%d,%d,%d)/n",id,r[0],r[1],r[2]);
   
   if(request(id,r,N))
   {
    printf("分配成功!/n");
   }
   else
   {
    printf("分配失敗!/n");
   }
  }
  else
  {
      //輸入申請信息
      input(r,N,&id);
      //檢查輸入
      if(check(id,r[0],r[1],r[2]) == false)
      {
       printf("/n輸入錯誤請檢查后重新輸入/n");
       continue;
      }
      //執行   
      if(request(id,r,N))
      {
       printf("Request Secceed!/n");
      }
      else
      {
       printf("Request Fail!/n");
      }         
  }
  //顯示當前系統資源和進程情況
     printf("系統可用資源:/n");
  print(Available,N);
  
  printf("進程%d的最大資源需求:/n",id);
  print(Max[id],N);
  
  printf("進程%d已經分配資源:/n",id);
  print(Allocation[id],N);  
  
     //提示是否繼續n或N退出
  printf("/nContinue?(Y/N)!/n");
  control = getch();
  if(control == 'n' || control == 'N')
  {
   break;
  }
 }
 return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM