实验三进程调度模拟程序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的主要内容,如果未能解决你的问题,请参考以下文章