处理器调度实验报告

一、实验内容

   按优先数调度算法实现处理器调度。

二、实验目的

在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。

三、实验原理

     设计一个按优先数调度算法实现处理器调度的程序。

 (1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:

其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5

指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。

要求运行时间——假设进程需要运行的单位时间数。

优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。

状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。

(2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。

(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例:

  队首标志

         K2   

(4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:

优先数-1

要求运行时间-1

来模拟进程的一次运行。

提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。

(5) 进程运行一次后,若要求运行时间¹0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。

(6) 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。

(7) 在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。

(8) 为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。

四、算法流程图

五、源程序及注释

#include <stdio.h>

#include<stdlib.h>

#include<malloc.h>

typedef struct DATA

{

       char pname[10];//进程名

       float time;//要求运行时间数

       int ove;//优先级

       char flag;//状态

}DATA;

 typedef struct pcb

{

       DATA data;

       struct pcb *next;

}pcb;

int flag=5;//假设有五个进程

pcb* init(pcb *p)//初始化

{

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

       p->next = NULL;

       return p;

}

void show(pcb *p)//输出显示

{

       if(!flag)

       {

              printf("\n没有正在运行的进程,或进程已经全部执行完毕。\n");

       }    

       else

       {            printf("\n名称");

                     printf("   ");

                     printf("执行时间");

                     printf("   " );

                     printf("优先数");

                     printf("   " );

                     printf("状态\n");

              while(p->next)

              {     p=p->next ;

                     printf("%s",p->data .pname );

                     printf("          ");

                     printf("%1.0f",p->data .time );

                     printf("        " );

                     printf("%d",p->data .ove  );

                     printf("        " );

                     printf("%c\n\n",p->data .flag  );

              }

       }

}

void del(pcb *h)//进程执行完成后的删除

{

       pcb *p;   

       p=h;

       p=p->next;

       if(p->data .flag =='E')

       {

              printf("有一个进程执行完成:\n");

              printf("进程的名称为:%s\n",p->data .pname);

              p=p->next;

              h->next =p;

              flag--;

       }

}

void in(pcb *h)//从键盘中输入数据

{

       int i=0;

       pcb *pc,*l;

       pc=h;

       printf("请依次输入五个进程的名称、执行时间、优先数:   (输入时进程与进程之间用回车来隔开!)\n");

       for(i;i<flag;i++)

       {

              l=init(l); 

              scanf("%s%f%d",&l->data .pname ,&l->data .time ,&l->data .ove );

              rewind(stdin);

              if(!l->data .time )

              {

                     l->data .flag ='E';

              }

              else

              l->data .flag='R';

      

              l->next =NULL;

              pc->next =l;

              pc=pc->next ;

       }

}

void soar(pcb *p)//对于这五个进程按其优先级进行排序

{

       pcb *q;

       pcb *h;   

       int i=0;

       int j;

       q=init(q);

       h=p->next ;

       for(i;i<flag;i++)

       {

              for(j=0;j<(flag-1);j++)

              {

                     if(h->data .time )

                     {

                     if(h->data .ove<h->next ->data .ove )

                     {

                            q->data =h->data ;

                            h->data =h->next->data  ;

                            h->next->data =q->data ;

                     }

                     h=h->next ;

                     }

                     else

                     {

                     printf("有一个进程执行完成:\n");

                     printf("进程的名称为:%s\n",h->data .pname);

                     flag--;

                     }

              }

              h=p->next ;

       }

       if(flag)

       printf("\n目前优先级最高的进程的名称是:%s\n所以执行此进程!",p->next ->data .pname );

}

void run(pcb *h)//执行程序

{

       h=h->next;

       h->data .time --;

       h->data .ove --;

       if(!h->data .time )

       {

              h->data .flag ='E';

       }

}

void main()

{

       pcb *p;

       char c;

       p=init(p);

      

       in(p);

       soar(p);

       show(p);

       del(p);

       while(flag)

       {

       run(p);

       del(p);

       soar(p);

       show(p);

       c=getch();

       rewind(stdin);

       }

}

六、打印的程序运行时初值和运行结果

1、假设从键盘中输入的五个进程的名称、执行时间、优先数分别为:

a  5  6

b  6  5

c  4  4

d  1  2

e  3  3

按优先级排序后,其优先级最高的是a。

2、执行一次a后,再次进行排序,a的优先级为最高。以下程序循环执行。

接下来是b

3、当a进程执行完成后,程序会给一个提示。并从队列中删除此进程。

4、程序最后执行完成,整个程序运行结束。

七、实验小结

              此实验主要是用到链表来实现。用到的数据结构为:

typedef struct DATA

{

       char pname[10];//进程名

       float time;//要求运行时间数

       int ove;//优先级

       char flag;//状态

}DATA;

 typedef struct pcb

{

       DATA data;

       struct pcb *next;

}pcb;

先对五个进程按其优先级进行排序,然后找到优先级最高的进程执行。假设当中有进程执行完成,则要从链表中将其删除,并标志出来。不断执行直到进程执行完成。其难点在于对链表的排序及删除操作。

 

第二篇:处理器调度算法实验报告

实验三、处理器调度算法实验

计本一区队学号:

一、实习内容

选择一个调度算法,实现处理器调度。

二、实习目的

本实习模拟在单处理器环境下的处理器调度,加深了解处理器调度的工作。

三、实习题目

第一题:设计一个按优先数调度算法实现处理器调度的程序。

[提示]:

(1)假定系统有5个进程,每个进程用一个PCB来代表。PCB的结构为:

·进程名——如P1~P5。

·指针——按优先数的大小把5个进程连成队列,用指针指出下一个进程PCB的首地址。

·要求运行时间——假设进程需要运行的单位时间数。

·优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。

·状态——假设两种状态:就绪和结束,用R表示就绪,用E表示结束。初始状态都为就绪状态。

(2) 开始运行之前,为每个进程确定它的“优先数”和“要求运行时间”。通过键盘输入这些参数。

(3) 处理器总是选择队首进程运行。采用动态改变优先数的办法,进程每运行1次,优先数减1,要求运行时间减1。

(4) 进程运行一次后,若要求运行时间不等于0,则将它加入就绪队列,否则,将状态改为“结束”,退出就绪队列。

(5) 若就绪队列为空,结束,否则转到(3)重复。

2.程序中使用的数据结构及符号说明:

#define num 5//假定系统中进程个数为5

struct PCB{

      char ID;//进程名

      int runtime;//要求运行时间

      int pri;//优先数

   char state; //状态,R-就绪,F-结束

};

struct PCB pcblist[num];//定义进程控制块数组

3.源程序清单

//按优先数调度算法实现处理器调度的程序

#include

#include

#define num 5//假定系统中进程个数为5

struct PCB

{

 char ID;//进程名

 int runtime;//要求运行时间

 int pri;//优先数

 char state; //状态,R-就绪,F-结束

};

struct PCB pcblist[num];//定义进程控制块数组

void init()//PCB初始化子程序

{

  int i;

  for(i=0;i

  {

   printf("PCB[%d]:ID pri runtime \n",i+1);//为每个进程任意指定pri和runtime

   scanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime);

   pcblist[i].state='R';//进程初始状态均为就绪

   getchar();//接收回车符

  }

}

int max_pri_process()//确定最大优先级进程子程序

{

 int max=-100;//max为最大优先数,初始化为-100

 int i;

 int key;

 for(i=0;i

  {if(pcblist[i].state=='r')//r为辅助状态标志,表示正在运行

       return -1;//返回-1

   

   else

          if(max

          {

          max=pcblist[i].pri;//max存放每次循环中的最大优先数

          key=i;//将进程号赋给key

          }

 }

     if(pcblist[key].state=='F')//具有最大优先数的进程若已运行完毕

           return -1;//则返回-1

     else//否则

        return key;//将key作为返回值返回

}

void show()//显示子程序

{int i;

 printf("\n   ID  pri   runtime  state\n");

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

 for(i=0;i

  {

   printf("%s%6d%8d    %s\n",&pcblist[i].ID,pcblist[i].pri,pcblist[i].runtime,&pcblist[i].state);

}

printf(" press any key to continue...\n");

}

void run()//进程运行子程序

{int i,j;

 int t=0;//t为运行次数

 for(j=0;j

 {t+=pcblist[j].runtime;}//运行次数即为各个进程运行时间之和

  printf("\nbefore run,the conditon is:\n");

  show(); //调用show()子程序显示运行前PCB的情况

  getchar();//等待输入回车符

 for(j=0;j

   {while(max_pri_process()!=-1)//具有最大优先数的进程没有运行完,让其运行

     {

          pcblist[max_pri_process()].state='r';//将其状态置为r,表示其正在运行

 }

 for(i=0;i

 {if(pcblist[i].state=='r')

 {      pcblist[i].pri-=1;//将当前运行进程的优先数减1

        pcblist[i].runtime--;//要求运行时间减1

              {

if(pcblist[i].runtime==0)

                 pcblist[i].state='F';//运行完则将该进程状态置为结束

            else

            pcblist[i].state='R';//未运行完将其状态置为就绪

                  }

             

                        show();//显示每次运行后各PCB的情况

               getchar();//等待回车进入下一次运行

 }                   

 }

 }

}

 void main()//按动态优先数调度主程序

{

 init();//初始化各个进程PCB

 run();//进程调度模拟 

 }

运行后结果:

首先初始化

ID                 pri                 runtime

a                    5                   6

b                   6                   5

c                    4                   4

d                   1                   2

e                    3                   3

回车,继续运行:【直到状态都为F时结束】

运行的最后结果:

ID                 pri                 runtime          state

a                    -1                  0                   F

b                   1                   0                   F

c                    0                   0                   F

d                   -1                  0                   F

e                    0                   0                   F

实验结果分析:

实验最后结果出现优先数为负【-1】的情况,是因为运行时间大于优先数,而进程每运行1次,优先数减1,要求运行时间减1而导致的。

通过本次模拟实验,我加深了解处理器调度的工作。

相关推荐