操作系统实验进程调度

实验二  进程调度

实验内容

进程调度模拟实验。

实验目的

通过模拟进程调度算法,了解进程调度的过程并比较不同的调度算法的区别。

实验题目

设计一段程序来模拟优先级调度算法和时间片轮转算法。要求可以指定进程的数量、各进程需要CPU的时间和各进程的优先级。

实验提示

⑴进程调度算法是指处理机的分配策略。

优先数调度算法是指对每个进程确定一个优先数,进程调度总是让具有最高优先数的进程先使用处理机。如果进程具有相同的优先数,再按先来先服务的次序分配处理机。在本实例中采用动态优先数算法。

时间片轮转算法是指就绪进程按就绪的先后次序排成队列,每次总是选择就绪队列中的第一个进程占用处理机,但规定只能使用一个“时间片”。

⑵系统中的进程可以用进程控制块PCB来表示,PCB的结构定义如表5-8所示:

表5-8 PCB结构

⑶在进程调度时进程会交替的出现在运行、就绪和完成三种状态。可以定义三个链表来存放三种状态的进程。当进程运行时就把进程放入到运行链表中;当进程处于就绪状态时就将进程放入到就绪链表中;当进程运行完毕时就将进程放入到完成链表中。由于同一时刻运行的进程只能有一个,所以运行链表只能有一个结点。在实例程序中为了使程序更简洁忽略了进程的等待状态,仅运行了优先数调度算法,由于篇幅有限,仅显示部分结果,对于时间片轮转调度算法,请读者自行运行。

⑷主要变量及函数说明如表5-9所示:

表5-9 主要变量及函数说明

⒌ 实例代码

//进程调度算法proc.c

//运行环境Redhad9.0 gcc 4.0

#include <stdio.h>

#include <string.h>

typedef struct pcb          //定义PCB结构

{

       char name[20];  /*进程标识符*/

       int cputime;    /*进程占用CPU时间*/

       int prio;       /*进程优先数*/

       int needtime;   /*进程到完成还需要的CPU时间*/

       struct pcb *next;/*链指针*/

}PCB;

PCB *RUN,*READY,*RTAIL,*FINSH,*FTAIL;

void PRINTLINK(int t)/*输出3个队列*/

{

       PCB *p;

       printf("CPU运行次数:___%d___\n",t);

       printf("______________________\n");

       printf("进程名\t运行状态\t运行次数\t还需要运行次数\n");

       if(RUN!=NULL)

       {

         printf("%s\t运行\t%d\t%d\n",RUN->name,RUN->cputime,RUN->needtime);

          }

       else

              printf("*运行状态为空\n");

       p=READY;

       if(p!=NULL)

       {

          while(p!=NULL)

          {

                     printf("%s\t就绪\t%d\t%d\n",p->name,p->cputime,p->needtime);

                  p=p->next;

          }

        }

       else

              printf("*就绪队列为空\n");

       p=FINSH;

       if (p!=NULL)

       {

           while(p!=NULL)

              {

                     //printf(" 进程名字为:%s\n",p->name);

                     printf("%s\t完成\t%d\t%d\n",p->name,p->cputime,p->needtime);

                     p=p->next;

              }

       }

       else

              printf("*完成队列为空\n");

       getchar();

}

PCB *CPCBLINK()/*建立就绪队列*/

{

       printf("建立就绪队列\n\n");

       int i,n,nt,pr;

       PCB *p,*q,*head;

       n=0;

       while(1)

       {

       printf("请输入进程的个数(有效范围1-100):");

          scanf("%d",&n);

       printf("\n");

          if (n>=1&&n<=100)

                 break;

          else

                 printf("输入有误。请重新输入!\n");

          getchar();

          }

    head=(struct pcb* )malloc(sizeof(struct pcb));

       printf("输入第1个进程的名称:");

       scanf("%s",head->name);

       while(1)

       {

         printf("需要的运行时间:");

         scanf("%d",&nt);

         if(nt>0)

               break;

         else

         {

                printf("输入无效,重新输入!\n");

                getchar();

         }

       }

       head->needtime=nt;

       printf("优先数:");

       scanf("%d",&pr);

       head->prio=pr;

    head->cputime=0;/*进程已获得的运行时间*/

       head->next=NULL;

       q=head;

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

       {

        printf("\n");

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

           printf("输入第%d进程的名称:",i+1);

           scanf("%s",p->name);

           printf("需要的运行时间:");

           scanf("%d",&nt);

           p->needtime=nt;

           printf("优先数:");

           scanf("%d",&pr);

           p->prio=pr;

              p->cputime=0;/*进程已获得的运行时间*/

           p->next=NULL;

              q->next=p;

              q=p;

       }

    RTAIL=q;

       return head;   

}

void JXDLPX()/*就绪队列按优先级从大到小排序*/

{

  PCB *p,*q,*t;

  char s[10];

  int L=0,ct,pr,nt;

  p=READY;

  t=(struct pcb* )malloc(sizeof(struct pcb));

  while(p->next!=NULL)

  {

         L=0;

         q=p->next;

         t=p;

         while(q!=NULL)

         {

                if(t->prio<q->prio)

                {

                       t=q;

                       L=1;/*表示有比它优先级大的进程*/

                }

                q=q->next;

         }

         if(L==1)

         {

                strcpy(s,t->name);

                ct=t->cputime;

                pr=t->prio;

                nt=t->needtime;

          q=p->next;

                while(strcmp(q->name,s)!=0)

                       q=q->next;

                strcpy(q->name,p->name);

                q->cputime=p->cputime;   

             q->prio=p->prio;      

             q->needtime=p->needtime;

                strcpy(p->name,s);

                p->cputime=ct;   

             p->prio=pr;      

             p->needtime=nt;

         }

         p=p->next;

  }

}

void YXS()/*调用优先数调度算法*/

{

       PCB *p;

       int t=0,nt,ct,pr;

       printf("您选择的是:优先级调度算法\n");

       READY=CPCBLINK();/*建立就绪队列*/

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

       while(READY!=NULL)

              {

                JXDLPX();/*就绪队列按优先级从大到小排序*/

                p=READY;

                READY=READY->next;

                p->next=NULL;

                pr=p->prio;

                pr=pr-3;

                p->prio=pr;/*运行1次进程优先级缩小3*/

                nt= p->needtime;

                nt=nt-1;

                p->needtime=nt;

                ct=p->cputime;

                ct=ct+1;

                p->cputime=ct;

                RUN=p;

                PRINTLINK(t);/*输出3个队列*/

                if(  RUN->needtime<=0)/*若运行结束进入完成队列*/

                { 

                      if (FINSH==NULL)/*第1次进入完成队列*/

                      {

                             FINSH=p;

                             FTAIL=p;

                      }

                      else

                      {

                 FTAIL->next=p;

                             FTAIL=FTAIL->next;

                      }                                                                   

                       RUN=NULL;

                }

                else  /*若运行没结束进入就绪队列*/

                {

                       if (READY==NULL)/*当就绪队列为空*/

                       {

                              READY=p;

                              RTAIL=p;

                       }

                       else

                       {

                        RTAIL->next=p;

                           RTAIL=p;

                       }

                       RUN=NULL;

                }

                t++;

              }

}

void SJP()/*调用时间片循环轮转算法*/

{

       PCB *p;

       printf("您选择的是:时间片循环轮转调度算法\n");

    int t=0,nt,ct;

       READY=CPCBLINK();/*建立就绪队列*/

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

       while(READY!=NULL)

              {

                p=READY;

                READY=READY->next;

                p->next=NULL;

                nt= p->needtime; 

                nt=nt-2;

                if(nt<0)

                       nt=0;

                p->needtime=nt;

                ct=p->cputime;

                ct=ct+2;

                p->cputime=ct;

                RUN=p;

                PRINTLINK(t);/*输出3个队列*/

                if(  RUN->needtime<=0)/*若运行结束进入完成队列*/

                { 

                      if (FINSH==NULL)/*第1次进入完成队列*/

                      {

                             FINSH=p;

                             FTAIL=p;

                      }

                      else

                      {

                 FTAIL->next=p;

                             FTAIL=FTAIL->next;

                      }

                      RUN=NULL;

                }

                else/*若运行没结束进入就绪队列*/

                {

                       if (READY==NULL)/*当就绪队列为空*/

                       {

                              READY=p;

                              RTAIL=p;

                       }

                       else

                       {

                        RTAIL->next=p;

                           RTAIL=p;

                       }

                       RUN=NULL;

                }

                t++;

              }

}

/*主程序*/

int main()

{  

       int N;

       RUN=(struct pcb* )malloc(sizeof(struct pcb));

    while(1)

       {

              RUN =NULL;

           READY =NULL;

           RTAIL=NULL;

           FINSH=NULL;

          FTAIL=NULL;

              printf("===================\n");

              printf("进程调度算法演示程序 \n");

              printf("===================\n");

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

           printf("      2:时间片循环轮转算法\n");

           printf("      3:退出\n");

        printf("\n");

           printf("   请选择:");

           scanf("%d",&N);

              if(N==1)

                     YXS();/*调用优先数调度算法*/

              else if(N==2)

                     SJP();/*调用时间片循环轮转算法*/

              else if(N==3)

                   break;

        else

              {

                     printf("您输入的信息有误,请重新输入!\n\n");

                     getchar();

              }

       }

       printf("演示程序结束!\n\n");

    getchar();

return 0;

}

运行结果:

[root@redlinux ys]# gcc proc.c -o proc.o

[root@redlinux ys]#./proc.o

===================

进程调度算法演示程序

===================

      1:优先级调度算法

      2:时间片循环轮转算法

      3:退出

请选择:1↙

您选择的是:优先级调度算法

建立就绪队列

请输入进程的个数(有效范围1-100):3↙

输入第1个进程的名称:a↙

需要的运行时间:15↙

优先数:2↙

输入第2进程的名称:b↙

需要的运行时间:4↙

优先数:1↙

输入第3进程的名称:c↙

需要的运行时间:9↙

优先数:8↙

CPU运行次数:___0___

______________________

进程名  运行状态        运行次数        还需要运行次数

c       运行    1       8

a       就绪    0       15

b       就绪    0       4

*完成队列为空

CPU运行次数:___1___

______________________

进程名  运行状态        运行次数        还需要运行次数

c       运行    2       7

a       就绪    0       15

b       就绪    0       4

*完成队列为空

CPU运行次数:___2___

______________________

进程名  运行状态        运行次数        还需要运行次数

a       运行    1       14

c       就绪    2       7

b       就绪    0       4

*完成队列为空

CPU运行次数:___3___

______________________

进程名  运行状态        运行次数        还需要运行次数

c       运行    3       6

b       就绪    0       4

a       就绪    1       14

*完成队列为空

……               

……

CPU运行次数:___26___

______________________

进程名  运行状态        运行次数        还需要运行次数

a       运行    14      1

*就绪队列为空

b       完成    4       0

c       完成    9       0

CPU运行次数:___27___

______________________

进程名  运行状态        运行次数        还需要运行次数

*运行状态为空

*就绪队列为空

a       完成    15      0

b       完成    4       0

c       完成    9       0

相关推荐