模拟银行家算法实验-----一不小心暴露自己是河北工业大学的

本文介绍了一个简单的银行家算法实现,该算法用于操作系统中的死锁避免。通过用户输入资源数量、进程数量及各进程的最大需求来模拟资源分配过程,并判断系统是否处于安全状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                                                   操作系统----模拟银行家算法

        简介:2015级,大三狗,菜,人傻,哈哈,不过喜欢编程啦。贴个实验时做的算法,挺有意思。 如有需求,请做参考,什么换换参数名字呀,函数名字呀,调换代码位置呀,切换 输出的格式呀。。。知道期末很忙,但不要照着抄啦,等会儿都挂了就爽歪歪,哈哈哈,就这样。

以下是代码主要内容。。。与注释,被自己的贴心与善良感动。 本人脸皮厚,深知其菜。欢迎吐槽!


        #include"stdio.h"

#include"stdlib.h"
#include"string.h"
#include<iostream>
#include<cstring>
#include<vector>
#include<iomanip>
using namespace std;
//Available[i] 系统中现有的i类资源数
//Max[1:n,1:m] i进程对j 类资源的最大需求量
//Allocation[i,j] 进程i 已占有的j类资源的数量
//Need[i,j] 表示进程i还需要申请的j类资源的数量
//Need[i,j]=Max[i,j]-Allocation[i,j]
//Request[i,j]=k,进程i申请k个j类资源
//步骤1:如果Request[i,j]+Allocation[i,j]<Max[i,j],是:转向步骤2..否,需求量太大,报错
//步骤2:如果Request[i,j]<=Avaliable[j]成立,转向步骤3,如果不成立,阻塞
//步骤3:系统试探着把资源分配给进程P[i], 并修改下面数据结构当中的值:
//Available[i,j]=Available[j]-Request[i,j]
//Allocation[i,j]=Allocation[i,j]+Request[i,j]
//Need[i,j]=Need[i,j]-Request[i,j]

//步骤4:调用系统安全性检查算法,检查此次资源分配后系统是否处于安全状态。若安全,满足进程Pi的资源申请
//否则,将本次试探分配作废,恢复原来的资源分配状态。

//安全状态检查算法
//步骤1:初始化
// 工作向量: work[i:m]: 他表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素
//表示系统中的资源类型数。在执行安全算法开始时,Work=Available;
//bool 类型向量 Finish[1:n] 他表示是否有足够的资源分配给各个进程,使之运行完成。开始时令
//Finish[i]=false;当有足够资源非配给进程Pi时,置 Finish[i]=true;

//步骤2:
//寻找一个进程,Finish[i]=false 且Need[i,j]<=Work[j],找到执行步骤3,找不到执行步骤4

//步骤3:释放资源,进程得以完成:Work[j]=Work[j]+Allocation[i,j],Finish[i]=true,返回步骤2
//步骤4:Finish全为true,则为true,否则则是false,不安全
//时间复杂度 O(mxn^2)


int  n,m;
int &resource_num=n;
int &process_num=m;
const int MAX_PROCESS=50;
const int MAX_RESOURCE=50;
struct info
{
int P_MAX[MAX_RESOURCE];//声明所需要的最大的资源数

int allocation[MAX_RESOURCE];//进程已经获得资源数
int need[MAX_RESOURCE];  //进程还需获得资源数
}PROCESS[MAX_PROCESS];  //进程
int available[MAX_RESOURCE];//最大资源类型数为50个
int request[MAX_RESOURCE];  //试探分配的资源

void init()
{

    int i,j;
    printf("请输入资源种类数:");
    scanf("%d",&n);
        for(i=0;i<n;i++)
          {   printf("请输入第%d个资源的最大资源数:\n",i);
                scanf("%d",&available[i]);
            }
        printf("请输入进程数:");
    scanf("%d",&m);
    printf("请输入各进程对各资源的最大需求数:\n");
    for(i=0;i<m;i++)
          {  // printf("请输入第%d进程对各资源的最大需求数:\n",i);
              for(j=0;j<n;j++)
              {
                  cout<<"请输入第"<<i<<"个进程对"<<j<<"个资源的最大需求数:"<<endl;
                  scanf("%d",&PROCESS[i].P_MAX[j]);
                  PROCESS[i].allocation[j]=0;
                  PROCESS[i].need[j]=PROCESS[i].P_MAX[j];
              }
    }
          printf("\n");
}
int WORK[MAX_PROCESS];
int FINISH[MAX_PROCESS];
vector<int> ok_queue;
//进程数为 m,资源数为 n
int get_ok_process()
{
    int i,j,is_ok=1;
    for(i=0;i<process_num;i++)
    {
        if(FINISH[i]==false)
        {
        for(j=0;j<resource_num;j++)
        {
            if(PROCESS[i].need[j]>WORK[j])
            {
                is_ok=false;
            }
        }
        if(is_ok)
        {
          break;
        }else
        {
            is_ok=true;
        }
        }
    }
    return i;
}
int safe()
{

    ok_queue.clear();
    memset(FINISH,0,sizeof(FINISH));
    for(int i=0;i<resource_num;i++)
        WORK[i]=available[i];

    int i=get_ok_process();
    while(i<process_num)
    {
        for(int j=0;j<resource_num;j++)
        {
            WORK[j]+=PROCESS[i].allocation[j];
            FINISH[i]=true;

        }
         ok_queue.push_back(i);
        i=get_ok_process();
    }
    int is_safe=true;
    for(int haha=0;haha<process_num;haha++)
    {
       is_safe=is_safe&FINISH[haha];
    }
    return is_safe;
}

void print_Allocation(int times)
{
    cout.setf(ios::left);
    cout<<"-------------T"<<times<<"时刻"<<"资源分配图--------------"<<endl;

    cout<<setw(15)<<"-----PROCESS"<<
          setw(15)<<"--ALLOCATION"<<
          setw(15)<<"---------MAX"<<
          setw(15)<<"--------NEED"<<
          setw(15)<<"---AVAILABLE"<<endl;
    for(int i=0;i<process_num;i++)
    {

        cout<<"P"<<setw(15)<<i;
        for(int j=0;j<resource_num;j++)
        cout<<setw(5)<<PROCESS[i].allocation[j];
         for(int j=0;j<resource_num;j++)
        cout<<setw(5)<<PROCESS[i].P_MAX[j];
         for(int j=0;j<resource_num;j++)
        cout<<setw(5)<<PROCESS[i].need[j];
         for(int j=0;j<resource_num;j++)
        cout<<setw(5)<<available[j];
         cout<<endl;
    }
}
//ALLOCATION算法:
//Request[i,j]=k,进程i申请k个j类资源
//步骤1:如果Request[i,j]+Allocation[i,j]<Max[i,j],是:转向步骤2..否,需求量太大,报错
//步骤2:如果Request[i,j]<=Avaliable[j]成立,转向步骤3,如果不成立,阻塞
//步骤3:系统试探着把资源分配给进程P[i], 并修改下面数据结构当中的值:
//Available[j]=Available[j]-Request[j]
//Allocation[i,j]=Allocation[i,j]+Request[j]
//Need[i,j]=Need[i,j]-Request[j]

//步骤4:调用系统安全性检查算法,检查此次资源分配后系统是否处于安全状态。若安全,满足进程Pi的资源申请
//否则,将本次试探分配作废,恢复原来的资源分配状态。
void allo(int times)
{

   cout<<"第"<<times<<"次ALLOCATION:"<<endl;
   int i;
   cout<<"请输入您要分配的进程编号,上限为"<<process_num-1<<":"<<endl;
   cin>>i;
   if(i>=process_num||i<0)
   {
      cout<<"无此进程"<<endl;
      return ;
   }
       cout<<"请输入第"<<i<<"个进程"<<resource_num<<"个资源的ALLOCATION,用空格隔开:"<<endl;
       int is_ok=true;
       for(int j=0;j<resource_num;j++)
       {
           scanf("%d",&request[j]);
           if(request[j]>available[j]||
                   request[j]+PROCESS[i].allocation[j]
                   >PROCESS[i].P_MAX[j])
           {
               is_ok=false;
               break;
           }
       }
       if(is_ok)
       {
          for(int j=0;j<resource_num;j++)
          {
              available[j]=available[j]-request[j];
              PROCESS[i].allocation[j]+=request[j];
              PROCESS[i].need[j]-=request[j];
          }
          if(safe())
          {
             print_Allocation(times);
             cout<<"安全序列为:";
             for(int v=0;v<ok_queue.size();v++)
             {
                 cout<<ok_queue[v]<<" ";
             }
             cout<<endl;
          }
          else
          {
              cout<<"不安全,恢复原始分配状态"<<endl;
              for(int j=0;j<resource_num;j++)
              {
                  available[j]=available[j]+request[j];
                  PROCESS[i].allocation[j]-=request[j];
                  PROCESS[i].need[j]+=request[j];
              }
              print_Allocation(times);
          }
       }else
       {
           cout<<"需求量过大,无法满足,进程阻塞"<<endl;
       }






}

int main()
{
  int i;
  init();
  int times=0;
  do
  {
      printf("选择1--用银行家算法;选择0--退出:");
      scanf("%d",&i);
      if(i==1)
        allo(times++);
  }while(i==1);
  return 0;
}




实验目的】 1. 理解死锁的概念; 2. 用高级语言编写和调试一个银行家算法程序,以加深对死锁的理解。 【实验准备】 1. 产生死锁的原因  竞争资源引起的死锁  进程推进顺序不当引起死锁 2.产生死锁的必要条件  互斥条件  请求和保持条件  不剥夺条件  环路等待条件 3.处理死锁的基本方法  预防死锁  避免死锁  检测死锁  解除死锁 【实验内容】 1. 实验原理 银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。与预防死锁的几种方法相比较,限制条件少,资源利用程度提高了。缺点:该算法要求客户数保持固定不变,这在多道程序系统中是难以做到的;该算法保证所有客户在有限的时间内得到满足,但实时客户要求快速响应,所以要考虑这个因素;由于要寻找一个安全序列,实际上增加了系统的开销.Banker algorithm 最重要的一点是:保证操作系统的安全状态!这也是操作系统判断是否分配给一个进程资源的标准!那什么是安全状态?举个小例子,进程P 需要申请8个资源(假设都是一样的),已经申请了5个资源,还差3个资源。若这个时候操作系统还剩下2个资源。很显然,这个时候操作系统无论如何都不能再分配资源给进程P了,因为即使全部给了他也不够,还很可能会造成死锁。若这个时候操作系统还有3个资源,无论P这一次申请几个资源,操作系统都可以满足他,因为操作系统可以保证P不死锁,只要他不把剩余的资源分配给别人,进程P就一定能顺利完成任务。 2.实验题目 设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。 3.算法描述 我们引入了两个向量:Resourse(资源总量)、Available(剩余资源量) 以及两个矩阵:Claim(每个进程的最大需求量)、Allocation(已为每个进程分配的数量)。它们共同构成了任一时刻系统对资源的分配状态。 向量模型: R1 R2 R3 矩阵模型: R1 R2 P1 P2 P3 这里,我们设置另外一个矩阵:各个进程尚需资源量(Need),可以看出 Need = Claim – Allocation(每个进程的最大需求量-剩余资源量) 因此,我们可以这样描述银行家算法: 设Request[i]是进程Pi的请求向量。如果Request[i , j]=k,表示Pi需k个Rj类资源。当Pi发出资源请求后,系统按下述步骤进行检查: (1) if (Request[i]<=Need[i]) goto (2); else error(“over request”); (2) if (Request[i]<=Available[i]) goto (3); else wait(); (3) 系统试探性把要求资源分给Pi(类似回溯算法)。并根据分配修改下面数据结构中的值。 剩余资源量:Available[i] = Available[i] – Request[i] ; 已为每个进程分配的数量: Allocation[i] = Allocation[i] + Request[i]; 各个进程尚需资源量:Need[i] = Need[i]-Request[i]; (4) 系统执行安全性检查,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程以完成此次分配;若不安全,试探方案作废,恢复原资源分配表,让进程Pi等待。 系统所执行的安全性检查算法可描述如下: 设置两个向量:Free、Finish 工作向量Free是一个横向量,表示系统可提供给进程继续运行所需要的各类资源数目,它含有的元素个数等于资源数。执行安全算法开始时,Free = Available .标记向量Finish是一个纵向量,表示进程在此次检查中中是否被满足,使之运行完成,开始时对当前未满足的进程做Finish[i] = false;当有足够资源分配给进程(Need[i]<=Free)时,Finish[i]=true,Pi完成,并释放资源。 (1)从进程集中找一个能满足下述条件的进程Pi ① Finish[i] == false(未定) ② Need[i] D->B->A A 1 6 B 1 5 C 2 4 D 4 7 Available = (2) ; Resourse = (10) ; 测试结果如下 process number:5 resource number:4 resource series:6 3 4 2 assined matrix:p0:3 0 1 1 p1:0 1 0 0 p2:1 1 1 0 p3:1 1 0 1 p4:0 0 0 0 needed matrix: p0:1 1 0 0 p1:0 1 1 2 p2:3 1 0 0 p3:0 0 1 0 p4:2 1 1 0 p3-->p4-->p0-->p2-->p1 p3-->p4-->p0-->p1-->p2 p3-->p0-->p4-->p2-->p1 p3-->p0-->p4-->p1-->p2 p3-->p0-->p2-->p4-->p1 p3-->p0-->p2-->p1-->p4 p3-->p0-->p1-->p4-->p2 p3-->p0-->p1-->p2-->p4 it is safe,and it has 8 solutions
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值