计算机操作系统课程设计报告

《操作系统原理》

实 验 报 告

院 (部): 管理工程学院

专    业:信息管理与信息系统

实验项目:实验一 二 三 五

班    级:信管102

姓    名:

学    号:

  

引    言.......................................................................................................................... 4

实验一、模拟进程创建、终止、阻塞、唤醒原语.............................................................. 6

实验目的:............................................................................................................... 6

实验内容:............................................................................................................... 6

实验步骤:............................................................................................................... 7

实验代码:............................................................................................................... 7

程序运行结果及分析................................................................................................ 12

实验感想:................................................................................................................ 13

实验二、模拟进程调度功能............................................................................................ 14

实验目的:.............................................................................................................. 14

实验内容:.............................................................................................................. 14

实验步骤:.............................................................................................................. 14

实验代码:.............................................................................................................. 15

程序运行结果及分析................................................................................................ 19

实验感想:................................................................................................................ 20

实验三:模拟动态分区首次适应分配和回收算法............................................................. 20

实验目的:.............................................................................................................. 20

实验内容:.............................................................................................................. 20

实验步骤:.............................................................................................................. 20

实验代码:.............................................................................................................. 21

程序运行结果及分析................................................................................................ 27

实验感想:................................................................................................................ 28

实验五:模拟使用银行家算法判断系统的状态................................................................ 28

实验目的:.............................................................................................................. 28

实验步骤:.............................................................................................................. 28

实验代码:.............................................................................................................. 28

程序运行结果及分析................................................................................................ 33

实验感想:................................................................................................................ 34

引    言

    操作系统是信息管理与信息系统专业一门重要的专业理论课程,了解和掌握操作系统的基本概念、功能和实现原理,对认识整个计算机系统的工作原理十分重要。

操作系统实验是操作系统课程的一个重要组成部分,通过试验环节的锻炼使同学们不仅能够对以前的所学过的基础知识加以巩固,同时能够通过上机实验,对操作系统的抽象理论知识加以理解,最终达到融会贯通的目的,因此,实验环节是同学们理解、掌握操作系统基本理论的一个重要环节。

本实验指导书,根据教材中的重点内容设定了相应的实验题目,由于实验课程的学时有限,我们规定了必做题目和选做题目,其中必做题目必须在规定的上机学时中完成,必须有相应的预习报告和实验报告。选做题目是针对有能力或感兴趣的同学利用课余时间或上机学时的剩余时间完成。

 

  实验一、模拟进程创建、终止、阻塞、唤醒原语

实验目的:

        通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。

实验内容:

1、设计创建、终止、阻塞、唤醒原语功能函数。

2、设计主函数,采用菜单结构(参见后面给出的流程图)。

3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列中进程的变化情况。

实验步骤:

1、进程PCB中应包含以下内容:

2、系统总体结构:

计算机操作系统课程设计报告

计算机操作系统课程设计报告

实验代码:

#include

#include

struct PCB

{

        char name[4];

        int priority;

        int runtime;

        

        

};

void main()

{

       int x,t;

       int a=0;

       int k=0,r=1,i=0,j=0;//k为就绪队列总数,r堵塞队列总数

       char name[4];

       struct PCB pcb[10];

       struct PCB pcb1[10];

    struct PCB pcb2[10];

      

       printf("---------------------菜单---------------------\n\n\n");

    printf("0----退出系统\n");

    printf("1----创建进程\n");

    printf("2----堵塞进程\n");

       printf("3----唤醒进程\n");

       printf("4----终止进程\n");

       printf("5----显示进程\n");

    printf("------------------------------------------------\n");

   

       strcpy(pcb1[0].name,"s");//堵塞队列

       pcb1[0].priority = 2;

       pcb1[0].runtime = 3;

      

       //printf("%s  %d  %d",pcb1[0].name,pcb1[0].priority,pcb1[0].runtime);

      

   

      

       while(1)

       {

              printf("请输入你的选择:");

           scanf("%d",&x);

           if(x==0)

                   break;

           if(x==1)

              {

                 

                  printf("-----------------创建进程---------------\n");

                

                

                    

                     printf("进程名:");

               scanf("%s",&pcb[k].name);

                  printf("优先级:");

                  scanf("%d",&pcb[k].priority);

                  printf("运行时间:");

                  scanf("%d",&pcb[k].runtime);

                     k=k+1;

                

               

              }

              if(x==2)

              {

                     printf("-----------------堵塞进程---------------\n");

                     printf("请输入要查找的进程:");

                     scanf("%s",name);

                     for(j=0;j<=k;j++)

                     {

                           

                            if(strcmp(pcb[j].name,name)==0)

                            {

                                   t=j;

                                   strcpy(pcb2[a].name,pcb[t].name);

                          pcb2[a].priority = pcb[t].priority;

                          pcb2[a].runtime = pcb[t].runtime;

                    strcpy(pcb1[r].name,pcb2[a].name);

                          pcb1[r].priority = pcb2[a].priority;

                          pcb1[r].runtime = pcb2[a].runtime;

                             r=r+1;

                                   a=a+1;

                                   for(i=t;i<=k;i++)

                                   {

                                          strcpy(pcb[i].name,pcb[i+1].name);

                                       pcb[i].priority = pcb[i+1].priority;

                                       pcb[i].runtime = pcb[i+1].runtime;

                                         

                                   }

                                k=k-1;

                                   printf("将就绪序列调度为运行:");

                                   for(i=0;i

                                          printf("%s %d %d\n",pcb2[i].name,pcb2[i].priority,pcb2[i].runtime);

                                   printf("堵塞进程:\n");

                            for(j=0;j

                                    printf("%s %d %d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime);

                                   break;

                            }

                           

                           

                            else

                    

                                   printf("该进程已是堵塞进程!\n");

                            break;

                     }

              }

      

              if(x==3)

              {

                     printf("-----------------唤醒进程---------------\n");

                    

                     printf("请输入要唤醒的进程:");

                     scanf("%s",name);

                    

                     for(i=0;i

                     {

                            if(strcmp(pcb1[i].name,name)==0)

                            { 

                                   t=i;

                                   strcpy(pcb[k].name,pcb1[t].name);

                                    pcb[k].priority = pcb1[t].priority;

                                 pcb[k].runtime = pcb1[t].runtime;

                                    k=k+1;

                                   for(j=t;j

                                   {

                                          strcpy(pcb1[j].name,pcb1[j+1].name);

                                       pcb1[j].priority = pcb1[j+1].priority;

                                       pcb1[j].runtime = pcb1[j+1].runtime;

                                         

                                   }

                                r=r-1;

                     printf("就绪进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime);

                     printf("堵塞进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime);

                break;

                            }

                    

                            else

                                   printf("该堵塞进程为空,不能唤醒进程!\n");

                            break;

                     }

              }

              //for(j=0;j

                            //printf("%s %d %d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime);

              if(x==4)

              {

                     printf("-----------------终止进程---------------\n");

            printf("请输入你要终止的进程:");

                     scanf("%s",name);

                     for(i=0;i

                     {

                            if(strcmp(pcb[i].name,name)==0)

                            {

                                   t=i;

                                   for(j=t;j

                                   {

                                          strcpy(pcb[j].name,pcb[j+1].name);

                                       pcb[j].priority = pcb[j+1].priority;

                                       pcb[j].runtime = pcb[j+1].runtime;

                                         

                                   }

                                k=k-1;

                            }

                            if(strcmp(pcb1[i].name,name)==0)

                            { 

                                   t=i;

                                   for(j=t;j

                                   {

                                          strcpy(pcb1[j].name,pcb1[j+1].name);

                                       pcb1[j].priority = pcb1[j+1].priority;

                                       pcb1[j].runtime = pcb1[j+1].runtime;

                                         

                                   }

                                   r=r-1;

                            }

                     }

                     printf("就绪进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime);

                     printf("堵塞进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime);

              }

              if(x==5)

              {

                     printf("-----------------显示进程---------------\n");

                     printf("就绪进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb[j].name,pcb[j].priority,pcb[j].runtime);

                     printf("堵塞进程:\n");

                     for(j=0;j

                            printf("%s %d %d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime);

              }

             

       }

     

}

程序运行结果及分析

  1  运行结果

实验感想:

       通过设计并调试创建、终止、阻塞、唤醒原语功能,加深了对操作系统中进程控制功能的理解,并且掌握操作系统模块的设计方法和工作原理。更重要的是理解了操作系统的调度方法是就绪-运行-堵塞-唤醒-结束的过程。

  实验二、模拟进程调度功能

实验目的:

      通过本实验,进一步掌握进程调度的功能和实现原理。

实验内容:

1、 设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度算法等。

2、 进程调度功能作为一个函数scheduler,加入到实验题目一中。

3、 进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”的提示信息。

4、 若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执行。若运行完,应删除相应PCB。

实验步骤:

1、 在实验题目一中的主菜单中加入一个菜单项:6   调度,选择该菜单项后,系统进入进程调度。

2、 进程调度的结构:

计算机操作系统课程设计报告

实验代码:

#include

#include

void priority();

void time();

struct PCB

{

        char name[4];

        int priority;

        int runtime;

        

        

};

struct PCB pcb[5];

int q=5;

void main()

{

       int p,i;

      

       strcpy(pcb[0].name,"p1");//序列队列,优先级由高到低为1,2,3.....

       pcb[0].priority = 2;

       pcb[0].runtime = 3;

       strcpy(pcb[1].name,"p2");//序列队列

       pcb[1].priority = 3;

       pcb[1].runtime = 2;

       strcpy(pcb[2].name,"p3");//序列队列

       pcb[2].priority = 1;

       pcb[2].runtime = 4;

       strcpy(pcb[3].name,"p4");//序列队列

       pcb[3].priority = 5;

       pcb[3].runtime = 6;

       strcpy(pcb[4].name,"p5");//序列队列

       pcb[4].priority = 4;

       pcb[4].runtime = 5;

      

       printf("------------------------------进程调度子菜单------------------------------\n");

       printf("                           0---------退出系统\n");

       printf("                           1---------优先级调度\n");

       printf("                           2---------时间片调度\n");

    printf("\n\n显示所有进程\n");

       for(i=0;i<5;i++)

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

       printf("请选择您需要的功能选项:");

       scanf("%d",&p);

       printf("***********************\n");

while(1)

       {

       if(p==0)

              break;

       switch(p)

       {

       //case 0:

              //break;

       case 1:

              printf("优先级调度算法\n");

              priority();

              break;

       case 2:

              printf("时间片调度算法\n");

              time();

              break;

             

       }

       printf("请选择您需要的功能选项:");

       scanf("%d",&p);

       printf("***********************\n");

}

}

void priority()

{

       int i,j;

       int t=0,r=0;

       //int q=5;

    char name[2]=" ";

       for(i=0;i

              for(j=i;j

              {

                     if(pcb[i].priority>pcb[j].priority)

                     {

                        strcpy(name,pcb[i].name);

                         strcpy(pcb[i].name,pcb[j].name);

                         strcpy(pcb[j].name,name);

                         t=pcb[i].priority;

                         pcb[i].priority=pcb[j].priority;

                         pcb[j].priority=t;

                r=pcb[i].runtime;

                         pcb[i].runtime=pcb[j].runtime;

                        pcb[j].runtime=r;

                     }

              }

              printf("按优先级高低进行排序\n");

              for(i=0;i

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

              printf("***********************\n");

              printf("显示优先级最高的进程\n");

           printf("%s  %d  %d\n",pcb[0].name,pcb[0].priority,pcb[0].runtime);

              for(i=0;i

              {

                     strcpy(pcb[i].name,pcb[i+1].name);

                  pcb[i].priority = pcb[i+1].priority;

                     pcb[i].runtime = pcb[i+1].runtime;

              }

              printf("***********************\n");

              printf("使最高优先级进程处于执行状态(撤销该进程)\n");

              for(i=0;i

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

              q=q-1;

}

void time()

{

       int i,j,t;

    //int q=5;

       for(i=0;i

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

       for(i=0;i

       {

              pcb[i].runtime = pcb[i].runtime-1;

       }

    printf("***********************\n");

       printf("将每个执行进程的执行时间减去一个时间片。\n");

       for(i=0;i

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

       for(i=0;i

       {

              if(pcb[i].runtime<=0)

              {     t=i;

                     for(j=t;j

                                   {

                                          strcpy(pcb[j].name,pcb[j+1].name);

                                       pcb[j].priority = pcb[j+1].priority;

                                       pcb[j].runtime = pcb[j+1].runtime;

                                         

                                   }

             q=q-1;

              }

       }

       printf("***********************\n");

       printf("将进行结束的进程撤销。\n");

       for(i=0;i

       {

             

              printf("%s  %d  %d\n",pcb[i].name,pcb[i].priority,pcb[i].runtime);

       }

      

}

程序运行结果及分析

  

实验感想:

通过本实验,我进一步掌握进了程调度的功能和实现原理。熟练掌握了两种进程调度算法的应用,相信这对以后进一步学习操作系统、信息系统的开发都有很大的好处。

实验三:模拟动态分区首次适应分配和回收算法

实验目的:

通过本实验,可加深理解动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。

实验内容:

1、 设计动态分区首次适应分配、回收算法。

2、 设计“未分配区说明表”,格式为:

3、设计“已分配区说明表”,格式为:

4、 设计显示程序,将“未分配区说明表”和“已分配区说明表”的内容,显示在屏幕上。

初始分配从一个空闲区分配起,回收时要合并空区。

实验步骤:

1、 系统要求分配一个分区时,应输入:作业名、作业长度。

2、      回收一个分区时,应输入:回收的作业名。回收的分区请注意是否需要进行合并。

实验代码:

#include

#include

int MAX_SEGMENT=10;//最大碎片值

struct Partition                     //分区表目

{

       int Par_Size;   //分区大小

       int Par_No;            //分区序号或者名字

       int Addr;        //分区地址

       int IsUse;        //分区使用情况,0表示空闲,1表示使用

       Partition *pri;               //前向指针

       Partition *next;             //后向指针

};

Partition * Int()//函数,返回Partition类型指针

{            //初始化空闲分区表

       Partition *list,*H,*H1;

       list=(struct Partition *)malloc(sizeof(struct Partition));//malloc申请动态分配空间

       list->next=NULL;

       H=list;

       if(!list)

       {

              printf("\n错误,内存初始化分配失败!程序结束");

              exit(1);

       }

       H1=(struct Partition *)malloc(sizeof(struct Partition));

       printf("请预先输入分区总大小(以KB为单位):");

       scanf("%d",&H1->Par_Size);                    

       H1->Addr=0;

       H1->Par_No=0;

       H1->IsUse=0;

       H1->pri=H;

       H1->next=NULL;

       H->next=H1;////list--->H1

       return list;

}

Partition * InitFP()

{            //初始化已分配分区表

       Partition *FP,*F,*H;

       int i;

       FP=(struct Partition *)malloc(sizeof(struct Partition));

       FP->next=NULL;

       H=FP;

       for(i=0;i<10;i++)                 //已分配区先暂定分配十个表目

       {

              F=(struct Partition *)malloc(sizeof(struct Partition));

              if(!F)

              {

                     printf("\n错误,内存分配失败!程序结束");

                     exit(1);

              }

              F->Par_Size=0;

              F->Addr=0;

              F->Par_No=0;

              F->IsUse=0;

              F->next=NULL;

              H->next=F;

              F->pri=H;

              H=H->next;

       }

       return FP;

}

Partition * New_Process( Partition *list, Partition *FP)

{                   //为新的进程分配资源

       Partition *H,*P,*H1;

       int Size,Name,L;

       H=list;

       H1=FP->next;

       H=H->next;

       printf("请输入新作业的名称和大小(整数)\n");

       printf("作业名称:");

       scanf("%d",&Name);

       printf("作业大小(整数):");

       scanf("%d",&Size);

       while(H)

       {

              if(!H)             //表目已查完,无法分配

              {

                     printf("\n已无空闲分区,本次无法分配!");

                     return list;

              }

              else{

                     if(H->IsUse==0)                         //空表目

                            //if(H->Par_Size>=Size)              //大小满足,空闲分区大小》要分配的大小

                            if(H->Par_Size>=Size)         //大小满足,

                            {

                                   bool temp=false;

                                   if((H->Par_Size-Size)<=MAX_SEGMENT){//空闲分区大小-要分配的大小<碎片值,会产生碎片,将整块内存大小分配出去,

                                          Size=H->Par_Size;//分配的大小为整块内存

                                          temp=true;//会产生碎片

                                   }

                                   //其他情况就分配大小为请求大小,不会产生碎片,

                                   L=H->Addr;//保存空闲分地址

                                   if(temp){

                                          printf("该次内存分配会产生碎片,将整块内存大小%d分配出去!",Size);

                                   }else{

                                          printf("该次内存分配不会产生碎片");

                                          }

                                   break;

                            }

              }

              H=H->next;                         //否则,继续往下查找

       }

       if(H)

       {

              if(H->Par_Size>Size)    //大小满足,空闲分区大小》要分配的大小

              {

                     P=(struct Partition *)malloc(sizeof(struct Partition));                //分配新的表目,处理一条数据,分配一次内存

                     P->IsUse=1;

                     P->Addr=L;//指向空闲分区地址

                     P->next=H;                         //修改指针

                     H->pri->next=P;

                     P->pri=H->pri;

                     H->pri=P;                          

                     P->Par_Size=Size;//分配大小为要请求分配的大小

                     P->Par_No=Name;//名称

                     H->Par_Size-=Size;       //修改空闲分区,H所指区块大小减Size

                     H->Addr+=Size;//H所指区块地址加Size

              }else

              {

                     H->IsUse=1;          //大小相等的,把当前表项设置空表目

              }

              while(H1)

              {

                     if(H1->IsUse==0)

                     {

                            H1->Par_No=Name;

                            H1->Par_Size=Size;

                            H1->Addr=L;//保存已分配地址

                            H1->IsUse=1;//在已分配表中设置为已分配

                            break;

                     }

                     H1=H1->next;

              }

       }else

              printf("所申请资源已大过系统所拥有的,请重新输入!\n");

       return list;

}

Partition *Reclaim( Partition *list, Partition *FP)

{            //结束作业,资源回收,No为作业名,回收内存

    Partition * H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区

       int No;           //作业名

       H1=list;

       HF=FP;//可有可无?

       H1=H1->next;

       HF=FP->next;

       printf("请输入您想结束的作业名:");

       scanf("%D",&No);

       while(HF)//对已分配表进行操作

       {

              if(HF->Par_No==No)

              {

                     HF->IsUse=0;        //标志为空表目

                     break;//这时保存着HF所指分区的信息

              }

              HF=HF->next;

       }

       if(!HF)                  //如果找不到该作业,则提示出错

              printf("所输入的作业名称不正确,请重新输入!");

       else{

              while(H1)//对空闲表进行操作

              {

                     if(H1->Par_No==No)

                     {

                            H1->IsUse=0;        //标志为空表目

                            printf("内存回收成功");

                            break;

                     }

                     H1=H1->next;

              }

              H2=H1->next;//后分区

              H3=H1->pri;//前分区

              if(H2&&H2->IsUse==0)       //后接分区为空闲

              {

                     if(H2->next==NULL)           //判断后接分区是否为尾结点

                     {

                            H1->Par_Size+=H2->Par_Size;           //把H2合并到H1

                            H1->next=NULL;

                            free(H2);

                            printf("已回收%d大小内存",H1->Par_Size);

                     }else       //后分区不为空闲,表示已经被使用                      

                     {

                            H1->Par_Size+=H2->Par_Size;

                            H1->next=H2->next;

                            H2->next->pri=H1;

                            free(H2);

                            printf("已回收%d大小内存",H1->Par_Size);

                     }

              }

              if(H3&&H3->IsUse==0)              //前分区为空闲分区,则合并去前分区

              {

                     H3->Par_Size+=H1->Par_Size;

                     H3->next=H1->next;

                     if(H1->next!=NULL)            //若H1为尾结点

                            H1->next->pri=H3;

                     free(H1);

                     printf("已回收%d大小内存",H1->Par_Size);

              }

       }

       return list;

}

void Print( Partition *list, Partition *FP)

{            //输出已分配分区和空闲分区

       Partition *H1,*H2;

       H1=list->next;

       H2=FP;

       H2=H2->next;

       printf("**************************************************\n");

       printf("****************总分配分区表*******************\n");

       printf("分区序号   大小       开始地址   状态\n");

       while(H1)

       {

              printf("%d             %d  %d",H1->Par_No,H1->Par_Size,H1->Addr);

              if(H1->IsUse==1)

                     printf("   已分配\n");

              else

                     printf("   空表目\n");

              H1=H1->next;

       }

       printf("**************************************************\n");

}

void Main_Print( Partition *list, Partition *FP)

{            //主入口函数,进行菜单选择

       int op;

       while(1)

       {

              printf("\n--------------------------主菜单------------------------\n");

              printf("\n");

              printf("1.申请新的作业,分配内存\n");

              printf("2.结束作业,回收内存\n");

              printf("3.查看内存表\n");

              printf("4.退出系统\n");

              printf("\n请选择<1-4>:");

              scanf("%d",&op);

              switch(op)                    //根据输入,选择分支方向

              {

              case 1:

                     New_Process(list,FP);

                     break;

              case 2:

                     Reclaim(list,FP);

                     break;

              case 3:

                     Print(list,FP);

                     break;

              case 4:

                     break;

              default:

                     printf("\n选择错误,请重新选择!");

                     break;

              }

              if(op==4)

                     break;            //退出循环

       }

}

void main()

{                          //主函数入口

       struct Partition *list,*FP;

       list=Int();

       FP=InitFP();

       Main_Print(list,FP);

}

程序运行结果及分析

 

实验感想:

       通过本实验,加深了对动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。

实验五:模拟使用银行家算法判断系统的状态

实验目的:

了解进程管理的实现方法,理解和掌握处理进程同步问题的方法。

实验内容:

实现银行家算法、进程调度过程的模拟、读者-写者问题的写者优先算法。

实验步骤:

l  理解安全性算法和银行家算法的核心机制:

l  理解进程的三状态调度过程,及各状态间的转换关系;

l  设计读者--写者问题的写者优先算法;

实验代码:

#include

#include

#include

# define m 50

int no1;  //进程数

int no2;  //资源数

int r;

int allocation[m][m],need[m][m],available[m],max[m][m];

char name1[m],name2[m];                               //定义全局变量

void main()

{

       void check();

       void print();

       int i,j,p=0,q=0;

       char c;

       int request[m],allocation1[m][m],need1[m][m],available1[m];

      

       printf("----------------------银行家算法--------------------\n");

    printf("请输入进程总数:");

       scanf("%d",&no1);

       printf("请输入资源种类数:");

       scanf("%d",&no2);

    printf("请输入最大需求矩阵:\n");

       for(i=0;i

              for(j=0;j

                     scanf("%d",&max[i][j]);   //输入已知进程最大资源需求量

       printf("请输入当前分配矩阵:\n");

       for(i=0;i

              for(j=0;j

                     scanf("%d",&allocation[i][j]);  //输入已知的进程已分配的资源数

   

       for(i=0;i

              for(j=0;j

                     need[i][j]=max[i][j]-allocation[i][j]; //根据输入的两个数组计算出need矩阵的值

  

       printf("请输入可利用资源矩阵\n");

       for(i=0;i

              scanf("%d",&available[i]);       //输入已知的可用资源数

      

       print();  //输出已知条件

       check();  //检测T0时刻已知条件的安全状态

       if(r==1)  //如果安全则执行以下代码

       {

              do{

                     q=0;

            p=0;

                     printf("\n请输入请求资源的进程号(0~4):\n");

                     for(j=0;j<=10;j++)

                     {

                            scanf("%d",&i);

                            if(i>=no1)

                            {

                                   printf("输入错误,请重新输入:\n");

                                continue;     

                            }

                            else break;

                     }

                     printf("\n请输入该进程所请求的资源数request[j]:\n");

                     for(j=0;j

                            scanf("%d",&request[j]);

                     for(j=0;j

                            if(request[j]>need[i][j]) p=1; 

                            //判断请求是否超过该进程所需要的资源数

                            if(p)

                                   printf("请求资源超过该进程资源需求量,请求失败!\n");

                            else

                            {

                                   for(j=0;j

                                   if(request[j]>available[j]) q=1; //判断请求是否超过可用资源数

                                   if(q)

                                          printf("没有做够的资源分配,请求失败!\n");

                                   else                             //请求满足条件

                                   {

                                          for(j=0;j

                                          {

                                                 available1[j]=available[j]; 

                                                 allocation1[i][j]=allocation[i][j];

                                                 need1[i][j]=need[i][j];   

                                   //保存原已分配的资源数,仍需要的资源数和可用的资源数

                                                 available[j]=available[j]-request[j]; 

                                                 allocation[i][j]+=request[j];

                                                 need[i][j]=need[i][j]-request[j];

                            //系统尝试把资源分配给请求的进程

                                          }

                                          print();

                                          check();     //检测分配后的安全性

                                          if(r==0)   //如果分配后系统不安全

                                          {

                                                 for(j=0;j

                                                 {

                                                        available[j]=available1[j]; 

                                                     allocation[i][j]=allocation1[i][j];

                                                     need[i][j]=need1[i][j];

                    //还原已分配的资源数,仍需要的资源数和可用的资源数

                                                 }

                                                 printf("返回分配前资源数\n");

                                                 print();

                                          }

                                   }

                            }printf("\n你还要继续分配吗?Y or N ?\n");  

                            //判断是否继续进行资源分配

                                   c=getche();

              }while(c=='y'||c=='Y');

       }

}

void check()   //安全算法函数

{

       int k,f,v=0,i,j;

       int work[m],a[m];

       bool finish[m];

       r=1;

       for(i=0;i

              finish[i]=false;   // 初始化进程均没得到足够资源数并完成

       for(i=0;i

           work[i]=available[i];//work[i]表示可提供进程继续运行的各类资源数

       k=no1;

       do{

              for(i=0;i

              {

                     if(finish[i]==false)

                     {

                            f=1;

                            for(j=0;j

                                   if(need[i][j]>work[j])

                                          f=0;

                                   if(f==1)      //找到还没有完成且需求数小于可提供进程继续运行的资源数的进程

                                   {

                                          finish[i]=true;

                                          a[v++]=i;   //记录安全序列号

                                          for(j=0;j

                                                 work[j]+=allocation[i][j];  //释放该进程已分配的资源

                                   }

                     }

              }

              k--;      //每完成一个进程分配,未完成的进程数就减1

       }while(k>0);

       f=1;

       for(i=0;i

       {

              if(finish[i]==false)  

              {

                     f=0;

                     break;

              }

       }

       if(f==0)       //若有进程没完成,则为不安全状态

       {

              printf("系统处在不安全状态!");

              r=0;

       }

       else

       {

              printf("\n系统当前为安全状态,安全序列为:\n");

              for(i=0;i

                     printf("p%d  ",a[i]);  //输出安全序列

       }

}

void print()  //输出函数

{

       int i,j;

       printf("\n");

       printf("*************此时刻资源分配情况*********************\n");

       printf("进程名/号   |   最大需求矩阵     | 当前分配矩阵  |     需求矩阵    |\n");

    for (i = 0; i < no1; i++)

              {

                     printf("     p%d/%d     ",i,i);

                        

              for (j = 0; j < no2; j++)

                   {printf("%d    ",max[i][j]);}

                     for (j = 0; j < no2; j++)

                         {printf("   %d     ",allocation[i][j]);}

                    

                     for (j = 0; j < no2; j++)

                         {printf(" %d     ",need[i][j]);}

      

                     printf("\n");

              }

           printf("\n");

              printf("各类资源可利用的资源数为:");

              for (j = 0; j < no2; j++)

                  {printf(" %d",available[j]);}

              printf("\n");

}

程序运行结果及分析

  

实验感想:

银行家算法是避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。死锁的产生,必须同时满足四个条件,即一个资源每次只能由一个进程;第二个为等待条件,即一个进程请求资源不能满足时,它必须等待,但它仍继续保持已得到的所有其他资源;第三个为非剥夺条件,即在出现死锁的系统中一定有不可剥夺使用的资源;第四个为循环等待条件,系统中存在若干个循环等待的进程,即其中每一个进程分别等待它前一个进程所持有的资源。防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。

相关推荐