进程调度算法实验报告

操作系统实验报告(二)

实验题目:进程调度算法

实验环境:C++

实验目的:编程模拟实现几种常见的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。

实验内容:编程实现如下算法:

1.先来先服务算法;

2.短进程优先算法;

3.时间片轮转调度算法。

设计分析

程序流程图

1.先来先服务算法

2.短进程优先算法

3.时间片轮转调度算法

实验代码

1. 先来先服务算法

#include <iostream.h>

#define n 20

typedef struct

{

 int id;          //进程名

 int atime;         //进程到达时间

 int runtime;       //进程运行时间

}fcs;

void main()

{

 int amount,i,j,diao,huan;

    fcs f[n];

 cout<<"请输入进程个数:"<<endl;

 cin>>amount;

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

 {

  cout<<"请输入进程名,进程到达时间,进程运行时间:"<<endl;

  cin>>f[i].id;

  cin>>f[i].atime;

  cin>>f[i].runtime;

  }

 for(i=0;i<amount;i++)         //按进程到达时间的先后排序

 {                               //如果两个进程同时到达,按在屏幕先输入的先运行

  for(j=0;j<amount-i-1;j++)

  {  if(f[j].atime>f[j+1].atime)

   {diao=f[j].atime;

    f[j].atime=f[j+1].atime;

    f[j+1].atime=diao;

    huan=f[j].id;

    f[j].id=f[j+1].id;

    f[j+1].id=huan;

   }

  }

 }

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

 {

  cout<<"进程:"<<f[i].id<<"从"<<f[i].atime<<"开始"<<","<<"在"

   <<f[i].atime+f[i].runtime<<"之前结束。"<<endl;

  f[i+1].atime=f[i].atime+f[i].runtime;

 }

}

2. 短进程优先算法

#include<stdio.h>

#define n 5

#define num 5

#define max 65535

typedef struct pro

{  int PRO_ID;

   int arrive_time;

         int sum_time;

         int flag;

}Pro;//整数排序

    int bubble(int temp[])

    {

       int i,j,tem=0;

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

                  {  int lastX=1;

                           for(j=0;j<num-i;j++)

                           {  if(temp[j]>temp[j+1])

                                    {  tem=temp[j];

                                      temp[j]=temp[j+1];

                                      temp[j+1]=tem;

                                      lastX=0;

                                    }

                           }

                           if(lastX==1) break;

                  }

                  return temp[0];

 }

//进程排序

    Pro bubble(Pro p[])

    {

             int i,j;

                  Pro temp={0};

                  Pro s[num];

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

           {    s[i]=p[i];

                    }

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

                  {

                           int lastX=1;

                           for(j=0;j<num-i;j++)

                           {

                                    if(s[j].sum_time>s[j+1].sum_time)

                                    {

                                      temp=s[j];

                                      s[j]=s[j+1];

                                      s[j+1]=temp;

                                      lastX=0;

                                    }

                           }

                           if(lastX==1) break;

                  }

                  return s[0];

    }

void SPF(int p)

{

         if(n>0)

         {

             int i,j,k,l,tc=0;

                  Pro seq[n];

                  Pro temp_seq[n];

                  printf("短进程优先调度算法SPF\n");

                  printf("请依次输入5个进程的进程号、到达时间和执行时间\n");

                  printf("成员变量用逗号隔开;进程间用回车隔开\n");

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

                      scanf("%d,%d,%d",&seq[i].PRO_ID,&seq[i].arrive_time,&seq[i].sum_time);

                  }

                  printf("调度顺序是:\n");         

                  //初始化tc

                  int temp[num];

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

                  {

                 temp[i]=seq[i].arrive_time;

                  }

                  tc=bubble(temp);//tc是断点啊

//flag 表示对应i的pro的队列情况

//-1表示未进入过队列,0表示在队列中,1表示被清除了

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

                           seq[i].flag=-1;

                  }

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

                           for(j=0;j<n;j++){

                               if(seq[j].flag!=1&&seq[j].arrive_time<=tc){

                                        seq[j].flag=0;

                                    }

                           }

                for(j=0;j<n;j++){

                               temp_seq[j]=seq[j];

                               if(seq[j].flag!=0){

                                        temp_seq[j].sum_time=max;

                                    }

                           }

                      l=bubble(temp_seq).PRO_ID;

                           for(j=0;j<n;j++){

                                    if(l==seq[j].PRO_ID){

                                             k=j;

                                    }

                           }

                      tc=tc+bubble(temp_seq).sum_time;

                      seq[k].flag=1;

                      printf("%d",l);

                  }

                  printf("\n");

         }

}

void main()

{

         SPF(n);

}

3. 时间片轮转调度算法

头文件RR.h

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<ctype.h>

#define MaxNum 100

typedef struct pcb //定义进程控制块

{

         char Name[MaxNum];  //进程名

         int arrivetime; //到达时间

         int runtime;    //运行时间

         int wholetime;  //固定运行时间

         int FinishTime; //完成时间

         double WeightTime; //周转时间

         double WeightWholeTime;  //带权周转时间

         char state;     //运行后的状态

         struct pcb *next;

}PCB;

//全局变量

int N;               //实际进程数

double SumWT;         //周转时间之和

double SumWWT;        //带权周转时间之和

double AverageWT;     //平均周转时间

double AverageWWT;    //平均带权周转时间

typedef struct   //定义队列,封装头结点,指针分别指向队头和队尾

{

         PCB *front,*rear;

}queue;

queue *init()  //进程队列置空

{

         queue *head;

         head=(queue*)malloc(sizeof(queue));

         head->front=NULL;

         head->rear=NULL;

         return head;

}

int empty(queue *head) //检验队列是否为空

{

         return (head->front?0:1);

}

queue *append(queue *head,char c[MaxNum],int a,int r,char s)  //进程队列入队,往后插入

{

         PCB *p;

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

         strcpy(p->Name,c);

         p->arrivetime=a;

         p->runtime=r;

         p->wholetime=r;

         p->state=s;

         //p->FinishTime=0;

         //p->WeightTime=0;

         //p->WeightWholeTime=0;

         p->next=NULL;

         if(empty(head))

                  head->front=head->rear=p;

         else

         {

                  head->rear->next=p;

                  head->rear=p;

         }

         return head;

}

queue *creat(queue *head)   //创建进程队列

{

         char c[MaxNum];

         char s='R';

         int a,r,i;

         printf("请输入共有几个进程:\n");

         scanf("%d",&N);

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

         {

                  printf("请输入第%d 个进程的进程名:\n",i);

                  getchar();

                  gets(c);

                  printf("请输入第%d 个进程的到达时间:\n",i);

                  scanf("%d",&a);

                  printf("请输入第%d 个进程的服务时间:\n",i);

                  scanf("%d",&r);

                  head=append(head,c,a,r,s);

         }

         return head;

}

void print(queue *head)  //输入创建的进程队列

{

         PCB *p;

         p=head->front;

         if(!p)

                  printf("时间片轮转调度队列为空!\n");

         while(p)

         {

                  printf("Name=%s   arrivetime=%d   runtime=%d   state=%c",p->Name,p->arrivetime,p->runtime,p->state);

                  printf("\n");

                  p=p->next;

         }

}

/*******************时间片轮转法调度算法的实现**************************/

void RR(queue *head,int q)

{

         int t=head->front->arrivetime, lt=head->rear->arrivetime;

         if(head->front->runtime<q)

                  t=t+head->front->runtime;

         else

                  t=t+q;

         /****进程队列为不空才可调度*****/

         while(!empty(head))

         {

                  PCB *p1,*p2;

        printf("\n时刻   进程   运行后的状态\n");

                  /*第一种情况:当前运行的时间小于最后一个进程到达时间做一下操作*/

                  while(t<lt)

                  {

                           p1=head->front;

                           printf("%2d    %s",t,p1->Name);

                           p1->runtime=p1->runtime-q;

                           //1.运行时间小于0,删除队首

                           if(p1->runtime<=0)

                           {

                                    p1->state='C';

                                    printf("      %c\n",p1->state);

                                    p1->FinishTime=t;

                                    p1->WeightTime=p1->FinishTime-p1->arrivetime;

                                    p1->WeightWholeTime=p1->WeightTime/p1->wholetime;

                SumWT+=p1->WeightTime;

                                    SumWWT+=p1->WeightWholeTime;

                                    printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->Name,p1->Name,p1->WeightTime,p1->WeightWholeTime);

                                    head->front=p1->next;

                                    free(p1);

                           }

                           //2.运行时间大于0,向后找位置插入

                           else

                           {

                                    printf("       %c\n",p1->state);

                                    p2=p1->next;

                                    while(p2->next && p2->arrivetime != t)

                                    {

                                             p2=p2->next;

                                    }

                                    //此时无新进入队列的进程,有两种情况:1.不用找位置往后插入,队首不变,不做操作

                                    //2.找位置往后插入

                                    if(p2->arrivetime != t)

                                    {

                                             PCB *p3=p1,*p4;

                                             while(p3->next && p3->arrivetime<t)

                                             {

                                                      p4=p3;

                                                      p3=p3->next;

                                             }

                                             if(p3->arrivetime>t)

                                             {

                                                      if(p4!=p1)   //p1插在p4后,头为p1->next

                                                      {

                                                               head->front=p1->next;

                                                               p1->next=p4->next;

                                                               p4->next=p1;

                                                      }

                                                      else  //不做操作

                                                               p4=p3=p2=NULL;

                                             }

                                             else

                                                      p4=p3=p2=NULL;

                                    }

                                    //此时有新进入队列的进程时:p1插在新进入队列的进程p2后,队首为p1->next

                                    else

                                    {

                                             head->front=p1->next;

                                             p1->next=p2->next;

                                             p2->next=p1;

                                    }

                           }

                           //时刻变化

                      if(head->front->runtime<q)

                                    t=t+head->front->runtime;

                           else

                                    t=t+q;

                  }

                  /*************第一种情况结束**************/

                  /******************第二种情况:当期运行的时间大于最后一个进程到达的时间做以下操作*********************/

                  while(t>=lt)

                  {

                           p1=head->front;

                           printf("%2d    %s",t,p1->Name);

                           p1->runtime=p1->runtime-q;

                           //1.运行时间小于0,删除队首

                           if(p1->runtime<=0)

                           {

                                    p1->state='C';

                                    printf("      %c\n",p1->state);

                   p1->FinishTime=t;

                                    p1->WeightTime=p1->FinishTime-p1->arrivetime;

                                    p1->WeightWholeTime=p1->WeightTime/p1->wholetime;

                SumWT+=p1->WeightTime;

                                    SumWWT+=p1->WeightWholeTime;

                                    printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->Name,p1->Name,p1->WeightTime,p1->WeightWholeTime);

                                    //printf("时刻%2d进程%s运行结束",t,p1->pname);

                                    head->front=p1->next;

                                    free(p1);

                                   

                           }

                           //2.运行时间大于0,直接插在队尾

                           else

                           {

                                    printf("      %c\n",p1->state);

                                    //若原队列只有一个进程,不必往队尾插

                               if(!p1->next)

                                             head->front=p1;

                                     //若原队列有多个进程

                                    else

                                    {

                                             head->front=p1->next;

                                        head->rear->next=p1;

                                             head->rear=p1;

                                             p1->next=NULL;

                                    }

                           }

                           //时刻变化,队列为空时不做时刻变化

                           if(empty(head))

                                    return;

                           else

                           {

                                    if(head->front->runtime<q)

                                             t=t+head->front->runtime;

                                    else

                                             t=t+q;

                           }

                  }

                  /*******第二种情况结束*********/

                  }

         }

主程序Main.cpp

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<ctype.h>

#include "RR.h"

void main()

{

         queue *head;

         int q;

         head=init();

         head=creat(head);

         printf("\n您输入的时间片轮转进程队列为:\n");

         print(head);

         printf("\n请输入时间片轮转调度的时间片为:");

         scanf("%d",&q);

         //时间片轮转调度

         RR(head,q);

         AverageWT=SumWT/N;

         AverageWWT=SumWWT/N;

         printf("平均周转时间=%5.2f,平均带权周转时间=%5.2f",AverageWT,AverageWWT);

}

运行结果

先来先服务:

短进程:

时间片轮:

心得体会

这次的实验与上次的实验相比,在很多方面都有更多的难度,所以我们参考了别人很多的程序然后稍作了修改。但是由于自身知识不够,所以没能将三个算法都弄到一个大程序中,只能通过三个程序来实现,这一点是我们的不足。虽然如此,我们还是有了一定的收获,比如更加深刻了解到了先来先服务、短进程、时间片轮这三种作业的原理,而且这一过程中我们觉得时间片轮调度算法更具优势。

相关推荐