实验三进程调度模拟程序2.0

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验三进程调度模拟程序2.0相关的知识,希望对你有一定的参考价值。

实验三、进程调度模拟程序2.0

一、    实验目的

用C语言模拟进程调度程序,以加深对进程的概念及进程调度算法的理解。

二、    实验内容及要求

设计一个有 N个进程并发执行的进程调度模拟程序。

1、模拟进程数据的生成

用户选择输入每个进程的到达时间,所需运行时间,进程的运行时间以时间片为单位。

2、模拟调度程序的功能

按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法:

FCFS

SRTF

HRRF

RR

3、显示每种算法下各进程的调度执行顺序。

4、计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间。

5、 模拟数据结果分析:对同一组模拟数据,比较各算法的平均周转时间,周转系数。

三、    实验方法及结果测试

实现代码如下:

#include<stdio.h>

#include<stdlib.h>

#define MAX 100

/*定义进程结构体*/

typedef struct pcb {

    char name[30];//进程名称

    double responseRatio;//进程响应比

    int arriveTime;//进程到达时间

    int serveTime;//进程服务时间

    int finishTime;//进程完成时间

    int cpuTime;//进程占用CPU时间

    double roundTime;//周转时间

    double daiquanTime;//带权周转时间

    char state;//进程状态

} PCB;

 

PCB p[MAX];

int number;//进程数目

int time;//时间片长度

 

Input(PCB p[MAX],int n,char c) {

    int i;

    switch(c) {

       case 1:

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

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

              scanf("%s",&p[i].name);

              printf("第%d个进程的到达时间:",i+1);

              scanf("%d",&p[i].arriveTime);

              printf("第%d个进程的服务时间:",i+1);

              scanf("%d",&p[i].serveTime);

              printf("\\n");

           }

           break;

       case 2:

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

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

              scanf("%s",&p[i].name);

              printf("第%d个进程的到达时间:",i+1);

              scanf("%d",&p[i].arriveTime);

              printf("第%d个进程的服务时间:",i+1);

              scanf("%d",&p[i].serveTime);

              p[i].state=‘r‘;

              p[i].cpuTime=0;

              p[i].finishTime=0;

              printf("\\n");

           }

           break;

       case 3:

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

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

              scanf("%s",&p[i].name);

              printf("第%d个进程的到达时间:",i+1);

              scanf("%d",&p[i].arriveTime);

              printf("第%d个进程的服务时间:",i+1);

              scanf("%d",&p[i].serveTime);

              printf("\\n");

           }

           break;

       case 4:

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

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

              scanf("%s",&p[i].name);

              printf("第%d个进程的服务时间:",i+1);

              scanf("%d",&p[i].serveTime);

              printf("\\n");

           }

           break;

       case 0:

           break;

    }

}

 

Output(PCB p[MAX],int n,char c) {

    int i;

    switch(c) {

       case 1:

           printf("进程名称 到达时间 服务时间 完成时间 周转时间 带权周转时间\\n");

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

              printf("    %s\\t",p[i].name);

              printf("     %d\\t",p[i].arriveTime);

              printf("     %d\\t",p[i].serveTime);

              printf("     %d\\t",p[i].finishTime);

              printf("    %f\\t",p[i].roundTime);

              printf("%f",p[i].daiquanTime);

              printf("\\n");

           }

           break;

       case 2:

           printf("进程名称 到达时间 服务时间 当前时间 进程状态 完成时间   周转时间 带权周转时间\\n");

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

              printf("    %s\\t",p[i].name);

              printf("    %d\\t",p[i].arriveTime);

              printf("     %d\\t",p[i].serveTime);

              printf("       %d\\t",p[i].cpuTime);

              printf("%c\\t",p[i].state);

              printf("%d\\t",p[i].finishTime);

              printf("%f",p[i].roundTime);

              printf("  %f",p[i].daiquanTime);

              printf("\\n");

           }

           break;

       case 3:

           printf("进程名称 到达时间 服务时间 当前时间 进程状态 完成时间   周转时间 带权周转时间\\n");

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

              printf("    %s\\t",p[i].name);

              printf("    %d\\t",p[i].arriveTime);

              printf("     %d\\t",p[i].serveTime);

              printf("       %d\\t",p[i].cpuTime);

              printf("%c\\t",p[i].state);

              printf("%d\\t",p[i].finishTime);

              printf("%f",p[i].roundTime);

              printf("  %f",p[i].daiquanTime);

              printf("\\n");

           }

           break;

       case 4:

           printf("进程名称 服务时间\\n");

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

              printf("    %s\\t",p[i].name);

              printf("     %d\\t",p[i].serveTime);

              printf("\\n");

           }

           break;

       case 0:

           break;

    }

}

 

//按到达时间进行冒泡排序

ArriveTimeSort(PCB p[MAX],int n) {

    int i,j,flag;

    PCB temp;

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

       flag=0;

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

           if(p[j].arriveTime>p[j+1].arriveTime) {

              temp=p[j];

              p[j]=p[j+1];

              p[j+1]=temp;

              flag=1;

           }

       }

       if(flag=0) {

           break;

       }

    }

}

 

//按服务时间进行冒泡排序

ServeTimeSort(PCB p[MAX],int n) {

    int i,j,flag;

    PCB temp;

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

       flag=0;

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

           if(p[j].serveTime>p[j+1].serveTime) {

              temp=p[j];

              p[j]=p[j+1];

              p[j+1]=temp;

              flag=1;

           }

       }

       if(flag=0) {

           break;

       }

    }

}

 

CpuTimeCalculate(PCB p[MAX],int n) {

    int m=0,i=0;

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

       m = p[i].cpuTime+m;

    }

    return m;

}

 

Run(PCB p[MAX] , int n , char c) {

    int i,j,t;

    int m,k=0;

    PCB temp;

    switch(c) {

       case 1:

           p[0].finishTime=p[0].arriveTime+p[0].serveTime;

           p[0].roundTime=p[0].finishTime-p[0].arriveTime;

           p[0].daiquanTime=p[0].roundTime/p[0].serveTime;

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

              if(p[i].arriveTime<p[i-1].finishTime) {

                  p[i].finishTime=p[i-1].finishTime+p[i].serveTime;

                  p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                  p[i].daiquanTime=p[i].roundTime/p[i].serveTime;

              } else {

                  p[i].finishTime=p[i].arriveTime+p[i].serveTime;

                  p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                  p[i].daiquanTime=p[i].roundTime/p[i].serveTime;

              }

           }

           break;

       case 2:

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

              m = p[i].serveTime+m;

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

                  printf("请按回车键继续运行......!\\n");

                  getchar();

                  p[i].cpuTime++;

                  p[i].state=‘R‘;

                  p[i].serveTime--;

                  ServeTimeSort(p,n);

                  if(p[i].serveTime!=0) {

                     p[i].state=‘R‘;

                  } else {

                     p[i].state=‘F‘;

                     k=CpuTimeCalculate(p,n);

                     if(p[i].arriveTime<p[i-1].finishTime) {

                         p[i].finishTime=p[i].finishTime+k;

                         p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                         p[i].daiquanTime=p[i].roundTime/p[i].cpuTime;

                     } else {

                         p[i].finishTime=p[i-1].finishTime+k;

                         p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                         p[i].daiquanTime=p[i].roundTime/p[i].cpuTime;

                     }

                     Output(p,n,c);

                     printf("********第%d个进程的运行完成!********\\n",i+1);

                     break;

                  }

                  Output(p,n,c);

              }

           }

           break;

       case 3:

           p[0].finishTime=p[0].arriveTime+p[0].serveTime;

           p[0].roundTime=p[0].finishTime-p[0].arriveTime;

           p[0].daiquanTime=p[0].roundTime/p[0].serveTime;

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

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

                  if(p[j].arriveTime<=p[i-1].finishTime) {

                     for(t=i; t<=j; t++) {

                         p[t].responseRatio=(float)(p[t-1].finishTime-p[t].arriveTime)/p[t].serveTime;

                         if(p[t].responseRatio<p[j].responseRatio) {

                            temp=p[j];

                            p[j]=p[t];

                            p[t]=temp;

                         }

                     }

                  }

              }

              if(p[i].arriveTime<p[i-1].finishTime) {

                  p[i].finishTime=p[i-1].finishTime+p[i].serveTime;

                  p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                  p[i].daiquanTime=p[i].roundTime/p[i].serveTime;

              } else {

                  p[i].finishTime=p[i].arriveTime+p[i].serveTime;

                  p[i].roundTime=p[i].finishTime-p[i].arriveTime;

                  p[i].daiquanTime=p[i].roundTime/p[i].serveTime;

              }

           }

           break;

       case 4:

x:

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

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

                  if(p[j].serveTime == 0) {

                     break;

                  } else {

                     p[j].serveTime--;

                  }

              }

              Output(p,n,c);

           }

           printf("\\n───────────────────────\\n");

           getchar();

           if(p[n-1].serveTime!=0) {

              goto x ;

           }

           break;

       case 0:

           break;

    }

}

 

 

 

Calculate(PCB p[MAX] , int n ) {

    int i;

    float averRoundTime=0.0;//平均周转时间

    float averDaiquanTime=0.0;//平均带权周转时间

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

       averRoundTime=p[i].roundTime+averRoundTime;

       averDaiquanTime=(float)(p[i].daiquanTime+averDaiquanTime);

    }

    printf("\\n平均周转时间:%f",averRoundTime/(float)n);

    printf("\\n平均带权周转时间:%f\\n",averDaiquanTime/(float)n);

}

 

End(PCB p[MAX] , int n , char c) {

    int i;

    switch(c) {

       case 1:

           Output(p,n,c);

           Calculate(p,n);

           printf("********进程调度结束!********\\n");

           break;

       case 2:

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

              if(p[i].serveTime==0) {

                  p[i].state=‘F‘;

              }

           }

           Output(p,n,c);

           Calculate(p,n);

           printf("********进程调度结束!********\\n",i+1);

           break;

       case 3:

           Output(p,n,c);

           Calculate(p,n);

           printf("********进程调度结束!********\\n",i+1);

           break;

       case 4:

           printf("********进程调度结束!********\\n",i+1);

           break;

       case 0:

           break;

    }

}

 

FCFS(char c) {

    Input(p,number,c);

    system("cls");

    ArriveTimeSort(p,number);

    Output(p,number,c);

    getchar();

    Run(p,number,c);

    End(p,number,c);

}

 

SRTF(char c) {

    Input(p,number,c);

    system("cls");

    ArriveTimeSort(p,number);

    Output(p,number,c);

    getchar();

    Run(p,number,c);

    End(p,number,c);

}

 

HRRF(char c) {

    Input(p,number,c);

    system("cls");

    ArriveTimeSort(p,number);

    Output(p,number,c);

    getchar();

    Run(p,number,c);

    End(p,number,c);

}

 

RR(char c) {

    Input(p,number,c);

    system("cls");

    ArriveTimeSort(p,number);

    Output(p,number,c);

    printf("\\n───────────────────────\\n");

    getchar();

    Run(p,number,c);

    End(p,number,c);

}

 

Menu() {

    printf("\\n\\t  -----------------欢迎进入进程调度模拟程序-----------------\\n");

    printf("\\t    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\\n");

    printf("\\t    ┃                   可选择算法操作:                   ┃\\n");

    printf("\\t    ┣━━━━━━━━━━━━━┳━━━━━━━━━━━━━┫\\n");

    printf("\\t    ┃1.先来先服务调度算法      ┃2.最短剩余时间优先调度算法┃\\n");

    printf("\\t    ┣━━━━━━━━━━━━━╋━━━━━━━━━━━━━┫\\n");

    printf("\\t    ┃3.最高响应比优先调度算法  ┃4.时间片轮转调度算法      ┃\\n");

    printf("\\t    ┣━━━━━━━━━━━━━┻━━━━━━━━━━━━━┫\\n");

    printf("\\t    ┃                     0.退出系统                       ┃\\n");

    printf("\\t    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\\n");

}

 

main() {

    char choice; //算法编号选择

    char if_continue;//判断是否继续

    system("cls");//清屏

    do {

       if_continue=‘N‘;

       Menu();//显示菜单

       printf("请选择对应序号:");

       scanf("%d",&choice); //输入算法编号

       system("cls");

       switch(choice) {

           case 1:

              printf("\\n            *************进程调度算法(先来先服务调度算法)************\\n\\n");

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

              scanf("%d",&number); //输入进程数目

              printf("\\n");

              FCFS(choice);

              fflush(stdin);

              printf("\\n是否返回主目录?(Y/N):");

              if_continue=getchar();

              system("cls");

              break;

           case 2:

              printf("\\n            *************进程调度算法(最短剩余时间优先调度算法)************\\n\\n");

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

              scanf("%d",&number); //输入进程数目

              printf("\\n");

              SRTF(choice);

              fflush(stdin);

              printf("\\n是否返回主目录?(Y/N):");

              if_continue=getchar();

              system("cls");

              break;

           case 3:

              printf("\\n            *************进程调度算法(最高响应比优先调度算法)************\\n\\n");

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

              scanf("%d",&number); //输入进程数目

              printf("\\n");

              HRRF(choice);

              fflush(stdin);

              printf("\\n是否返回主目录?(Y/N):");

              if_continue=getchar();

              system("cls");

              break;

           case 4:

              printf("\\n            *************进程调度算法(时间片轮转调度算法)************\\n\\n");

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

              scanf("%d",&number); //输入进程数目

              printf("请输入时间片长度:");

              scanf("%d",&time);

              printf("\\n");

              RR(choice);

              fflush(stdin);

              printf("\\n是否返回主目录?(Y/N):");

              if_continue=getchar();

              system("cls");

              break;

           case 0:

              break;

           default:

              if_continue=‘Y‘;

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

              system("pause");

              system("cls");

              break;

       }

    } while(if_continue==‘y‘||if_continue==‘Y‘);

    printf("\\n  ********感谢您的使用********\\n");

}

测试结果:

1)先来先服务调度算法:

 技术分享

 技术分享

 技术分享

2)最短剩余时间优先调度算法:

技术分享 

 技术分享

 技术分享

3)最高响应比优先调度算法:

 技术分享

 技术分享

 技术分享

4)时间片轮转调度算法:

 技术分享

 技术分享

 技术分享

 技术分享

 技术分享

 技术分享

四、    实验总结

a)  该怎么说呢,理论上所有的进程调度理解起来并不难,但用程序语言模拟其过程就有点困难了,特别是算法;

b)  虽说这四个进程调度算法可以算是简单模拟出效果,但其中还有很多BUG,需要继续改进。

以上是关于实验三进程调度模拟程序2.0的主要内容,如果未能解决你的问题,请参考以下文章

实验三 进程调度模拟程序2.0

实验三进程调度模拟程序

实验三 进程模拟调度程序

实验三

实验二进程调度模拟程序1.0

进程调度模拟程序