操作系统课程设计报告1

东莞理工学院城市学院

《计算机操作系统》课程设计

        目:   通用处理机调度演示程序   

        业:          软件工程          

        级:          2012            

小组成员:        李伟强  廖泓燊       

指导教师:        彭义春老师          

        间:    2014.12.10  —2012.12.       

        点:        3B312                   

东莞理工学院城市学院计算机与信息科学系制

20## 12


此次的课程设计所选的题目为“通用处理机调度演示”,通过此次课设能够更加理解操作系统中处理机的工作方式,同时在设计不同算法的过程中,也可以明确的知道各种调度算法的使用优劣,视不同的环境条件下,调用不同的算法可也达到比较想要的结果。

目录

1.      概述

课程设计内容:

设计目的:在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个,也就是能运行的进程数大于处理机个数,为了使系统中的进程有条不紊地工作,必须选用某种调度策略,在一定的时机选择一个进程占有处理机。要求我们设计一个模拟处理机调度算法,以巩固和加深处理机调度的概念。

2. 课程设计任务及要求

2.1   设计任务

通用处理机调度演示系统,需要模拟进程调度的五种算法:先来先服务调度算法,短作业优先调度算法,高响应比优先调度算法,时间片轮转调度算法,静态优先权优先调度算法,时间片轮转算法。每个作业包括多个进程,进程可以并发,每一个进程用一个进程类表示,进程类包含如下信息:PCB名称,进入内存时间,服务时间,状态标志,进程大小,内部PCB标志,进程的优先级。既可以用户自己输入相关进程,又可以读取外部文件,能够比较同一组数据在不同调度算法下的平均周转时间和平均带权周转时间。因为多数信息需要在执行过程中进行数据处理和动态显示,要求直观而规范的呈现演示过程

2.2设计要求

(1)进程调度算法包括:时间片轮转算法、先来先服务算法、短作业优先算法、静态优先权优先调度算法、高响应比调度算法。

(2)每一个进程有一个PCB,其内容可以根据具体情况设定。

(3)进程数、进入内存时间、要求服务时间、作业大小、优先级等均可以在界面上设定。

(4)可读取样例数据(要求存放在外部文件中)进行进程数、进入内存时间、时间片长度、作业大小、进程优先级的初始化。

(5)可以在运行中显示各个进程的状态:就绪、执行(由于不要求设置互斥资源与进程间的同步关系,故只有两种状态)。

(6)采用可视化界面,可在进程调度过程中随时暂停调度,查看当前进程的状态以及相应的阻塞队列。

(7)有性能比较功能,可比较同一组数据在不同调度算法下的平均周转时间。

(8)具有一定的数据容错性。

3. 算法及数据结构

3.1算法的总体思想

3.2先来先服务算法模块

3.2.1 功能

系统将按照作业到达的先后次序来进行调度,或者优先考虑在系统中等待时间最长的作业,不管作业所需执行时间的长短,从后备作业队列中选择几个最先进入该队列的作业,将它们调入内存,为它们分配内存和创建进程,然后放入就绪队列。

3.2.2          数据结构(包括变量的定义,要注释!)

void run_FCFS(pcb *p1) //运行未完成的进程

time = p1->arriveTime > time? p1->arriveTime:time; 

p1->startTime=time; 

printf("\n时刻:%d,  当前开始运行作业%s\n\n",time,p1->name);  time+=p1->serviceTime; 

p1->state='T'; 

p1->endTime=time; 

p1->lastTime=p1->endTime-p1->arriveTime; 

p1->lsTime=p1->lastTime/p1->serviceTime;  

x+=p1->lastTime;  

y+=p1->lsTime;  

printf("   arrivetime  servetime  startime  endtime  lastime   lstime \n");   

printf("%6d  %10d  %10d  %8d  %10.1f  %10.2f \n ",p1->arriveTime,p1->startTime, p1->serviceTime,p1->endTime,p1->lastTime,p1->lsTime);    

void FCFS() //找到当前未完成的进程 调度算法程序设计实验报告

{    int i; 

 p=head;   

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

{       

if(p->state=='F')   

{     

q=p;    //标记当前未完成的进程    

run_FCFS(q);    }    

p=p->next;   } } 

void getInfo()          //获得进程信息并创建进程

{  int num; 

printf("\n进程个数:"); 

scanf("%d",&n); 

for(num=0;num<n;num++) 

{  

p=(pcb *)malloc(sizeof(pcb));

printf("依次输入:\n进程名 到达时间 服务时间\n");  

scanf("%s\t%d\t%d",&p->name,&p->arriveTime,&p->serviceTime);

3.2.3          算法(流程图表示,或伪C表示)

根据流程判断得到运行队列的方法

3.3短作业优先算法模块

3.3.1功能

以作业长短计算优先级,作业越短,优先级越高,将从外存的作业后备队列中选择若干个估计运行事件最短的作业,优先将它们调入内存运行。

3.3.2 数据结构

RunTask(int   nextTaskID)

{

       taskes[nextTaskID].operation=1;

       taskes[nextTaskID].startTime=currenttime;

       taskes[nextTaskID].endTime=currenttime+taskes[nextTaskID].serveTime;

       taskes[nextTaskID].lastTime=taskes[nextTaskID].endTime-taskes[nextTaskID].arriveTime;

       taskes[nextTaskID].lsTime=taskes[nextTaskID].lastTime/(taskes[nextTaskID].serveTime*1.0);

       currenttime+=taskes[nextTaskID].serveTime;

}

3.3.3算法

3.4高响应比优先调度模块

3.4.1功能

为作业引入一个动态优先级,若作业等待时间相同,则服务事件越短,优先级越高,因而类似于SJF算法,当要求的服务事件相同时,作业的优先权决定其等待事件,因而该算法类似FCFS算法,对于长作业的优先级,可以随等待时间的增加而提高。

3.4.2数据结构

3.4.3算法

3.5静态优先权调度模块

3.5.1功能

3.5.2 数据结构

priority(char algo)

{

  while(run!=NULL)

  {

  run->cputime+=1;

  run->needtime-=1;

  run->prio-=3;

  if(run->needtime==0)

  {

      run->next=finish;

    finish=run;

   run->state='F';

   run=NULL;

      firstin();       

   }

   else

   {

     if((ready!=NULL)&&(run->prio<ready->prio))

     {

      run->state='W';

      insert1(run);

      run=NULL;

      firstin();

    }

   }

   prt(algo);

  }

 

}

3.5.3算法

3.3时间片轮转调度算法模块

3.6.1功能

3.6.2 数据结构

void rcreate_task(char algo)

{

  PCB *p;

 int i,time;

 char na[10];

 ready=NULL;

 finish=NULL;

 run=NULL;

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

 {

  p=(PCB*)malloc(sizeof(PCB));

  printf("Enter the name of process: ");

  scanf("%s",na);

   printf("Enter the time of process: ");

  scanf("%d",&time);

  strcpy(p->name,na);

  p->cputime=0;

  p->needtime=time;

  p->count=0;

  p->state='W';

  p->round=2;

  if(ready!=NULL)

  {

  insert2(p);

  }

  else

  {

    p->next=ready;

    ready=p;

    tail=p;

  }

  }

  printf("Output the waiting processes information:\n");

  prt(algo);

 run=ready;

 ready=ready->next;

 run->state='R';

}

3.6.3算法

4. 程序设计与实现

4.1 程序流程图

 

4.2 程序代码(要注释)

4.3 实验结果

时间片轮转算法

先来先服务

短作业优先调度算法

静态优先级调度算法

高响应比优先调度算法

 

5. 结论

6. 收获、体会和建议。

7. 参考文献。

(以下是参考文献的格式)

[1] 赛奎春,张雨.Visual C++ 工程应用与项目实践[M].北京:海洋出版社,2005

[2]任建武,闾国年,王桥.多层体系GIS与模型集成研究[J].测绘学报,2003,2:

78-182。

[3] ESRI中国(北京)有限公司网站[EB/OL].http://www.esrichina-bj.cn 。

说明:以后毕业论文的参考文献格式就是这样,文章或书名后面中括号的内容表示很重要,解释如下:

[M]表示来源于书籍,[J]表示来源于期刊杂志,[EB/OL]表示来源于网上的资料

 

第二篇:计算机操作系统课程设计报告[1]

《操作系统原理》

实 验 报 告

院 (部): 管理工程学院

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

实验项目:实验一 二 三 五

班    级:信管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中应包含以下内容:

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

2、系统总体结构:

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

实验代码:

     

#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、进程调度的结构:

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

实验代码:

#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");

}

程序运行结果及分析

  

实验感想:

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

相关推荐