先来先服务FCFS和短作业优先SJF进程调度算法
1.实验目的:
通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
2.实验内容
问题描述:
设计程序模拟进程的先来先服务FCFS和短作业优先SJF调度过程。假设有n个进程分别在T1, … ,Tn时刻到达系统,它们需要的服务时间分别为S1, … ,Sn。分别采用先来先服务FCFS和短作业优先SJF进程调度算法进行调度,计算每个进程的完成时间、周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
程序要求:
1)进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;选择算法1-FCFS,2-SJF。
2)要求采用先来先服务FCFS和短作业优先SJF分别调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;
3)输出:要求模拟整个调度过程,输出每个时刻的进程运行状态,如“时刻3:进程B开始运行”等等;
4)输出:要求输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
实现提示:
用C++语言实现提示:
1)程序中进程调度时间变量描述如下:
static int MaxNum=100;
int ArrivalTime[MaxNum];
int ServiceTime[MaxNum];
int FinishTime[MaxNum];
int WholeTime[MaxNum];
double WeightWholeTime[MaxNum];
double AverageWT_FCFS,AverageWT_SJF;
double AverageWWT_FCFS,AverageWWT_SJF;
2)进程调度的实现过程如下:
变量初始化;
接收用户输入n,T1, … ,Tn,S1, … ,Sn;算法选择1-FCFS,2-SJF;
按照选择算法进行进程调度,计算进程的完成时间、周转时间和带权周转时间;
计算所有进程的平均周转时间和平均带权周转时间;
按格式输出调度结果。
3.程序主要构成部分及其算法说明
void FCFS(){
int i;
//根据达时间排序
sortArrivalTime();
//FCFS计算第一个进程的时间
pro[0].FinishTime = pro[0].ArrivalTime + pro[0].ServiceTime;
pro[0].WholeTime = pro[0].FinishTime- pro[0].ArrivalTime;
pro[0].WeightWholeTime = pro[0].WholeTime/pro[0].ServiceTime;
pro[0].StartTime = pro[0].ArrivalTime;
//计算每个进程的时间
for(i=1;i<n;i++) {
getTime(i);
SumWT_FCFS += pro[i].WholeTime;
SumWWT_FCFS += pro[i].WeightWholeTime;
}
SumWT_FCFS += pro[0].WholeTime;
SumWWT_FCFS += pro[0].WeightWholeTime;
AverageWT_FCFS =SumWT_FCFS/n;
AverageWWT_FCFS = SumWWT_FCFS/n;
//输出各时间
cout<<"ID"<<"\t"<<"到达时间"<<"\t"<<"服务时间"<<"\t"<<"完成时间"<<"\t"<<"周转时间"<<"\t"<<"带权周转时间"<<endl;
for(i=0;i<n;i++) {
cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t"<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<endl;
};
cout<<"FCFS平均周转时间: "<<AverageWT_FCFS<<endl;
cout<<"FCFS带权平均周转时间: "<<AverageWWT_FCFS<<endl;
//FCFS输出各时间状态
outTime(n);
}
void SJF(){
int i;
//根据达时间排序
sortArrivalTime();
//计算第一个进程的各时间
pro[0].FinishTime = pro[0].ArrivalTime + pro[0].ServiceTime;
pro[0].WholeTime = pro[0].FinishTime- pro[0].ArrivalTime;
pro[0].WeightWholeTime = (double)pro[0].WholeTime/(double)pro[0].ServiceTime;
pro[0].StartTime = pro[0].ArrivalTime;
//计算每个进程的时间
for(i=1;i<n;i++) {
sortServiceTime(i);
getTime(i);
SumWT_SJF += pro[i].WholeTime;
SumWWT_SJF += pro[i].WeightWholeTime;
}
SumWT_SJF += pro[0].WholeTime;
SumWWT_SJF += pro[0].WeightWholeTime;
AverageWT_SJF = SumWT_SJF/n;
AverageWWT_SJF = SumWWT_SJF/n;
//输出各时间
cout<<"ID"<<"\t"<<"到达时间"<<"\t"<<"服务时间"<<"\t"<<"完成时间"<<"\t"<<"周转时间"<<"\t"<<"带权周转时间"<<endl;
for(i=0;i<n;i++) {
cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t"<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<endl;
};
cout<<"SJF平均周转时间: "<<AverageWT_SJF<<endl;
cout<<"SJF带权平均周转时间: "<<AverageWWT_SJF<<endl;
//SJF输出各时间状态
outTime(n);
}
//已到达的进程服务时间排序
void sortServiceTime(int a) {
int i,j;
//进程的到达时间小于上一个进程的完成时间,则其加入到就绪队伍中
for(i=a;i<n;i++) {
if(pro[i].ArrivalTime<= pro[a-1].FinishTime)
pro[i].ServiceTime_SJF = pro[i].ServiceTime;
}
//将就绪队伍中的进程按服务时间进行排序
//采用冒泡排序对服务时间进行排序
for(i=a;i<n;i++) {
for(j=i+1;j<n;j++) {
if(pro[i].ServiceTime_SJF>pro[j].ServiceTime_SJF && pro[i].ServiceTime_SJF != 0 && pro[j].ServiceTime_SJF != 0) {
temp= pro[i];
pro[i]= pro[j];
pro[j]= temp;
}
}
}
}
4.运行结果
5.实验源码
#include <iostream>
#include <iomanip>
using namespace std;
//定义进程的结构体
typedef struct{
char ID;//进程名字
double ArrivalTime;//到达时间
double ServiceTime;//服务时间
double ServiceTime_SJF;//SJF排序用的服务时间
double FinishTime;//完成时间
double StartTime;//各进程的开始执行时间
double WholeTime;//周转时间
double WeightWholeTime;//带权周转时间
}PRO;
static int MaxNum=100; //最大进程数
static int n=0;//进程数
static PRO pro[100]; //进程结构体
static PRO temp; //进程结构
static int choose;//选择的算法
static double SumWT_FCFS=0,SumWT_SJF=0;//周转时间总和
static double SumWWT_FCFS=0,SumWWT_SJF=0;;//带权周转时间总和
static double AverageWT_FCFS=0,AverageWT_SJF=0;//平均周转时间
static double AverageWWT_FCFS=0,AverageWWT_SJF=0;//平均带权周转时间
void Input();//输入进程数、各进程到达、服务时间
void chooseAlgorithm();//选择算法
void sortArrivalTime();//根据达时间排序
void sortServiceTime(int a);//已到达的进程服务时间排序
void getTime(int i);//计算
void outTime(int a);//输出各时间状态
void FCFS();
void SJF();
int main(){
int i,j;
for(i=0;i<MaxNum;i++) {
pro[i].ID = i+65;//给进程命名
}
Input();
chooseAlgorithm();
return 0;
}
//输入进程数、各进程到达、服务时间
void Input() {
cout<<"请输入进程个数n(不大于100):";
cin>>n;
cout<<"请输入每个进程的到达时间:"<<endl;
for (int i=0;i<n;i++)
{
cin>>pro[i].ArrivalTime;
}
cout<<"请输入每个进程的服务时间:"<<endl;
for (int i=0;i<n;i++)
{
cin>>pro[i].ServiceTime;
}
}
void chooseAlgorithm()
{
cout<<"请选择算法"<<endl;
cout<<"1为FCFS(先来先服务)"<<endl;
cout<<"2为SJF(短作业优先)"<<endl;
cin>>choose;
if (choose==1){
FCFS();
}
else if(choose==2){
SJF();
}
else{
cout<<"输入错误,请重新输入"<<endl;
//重新进入选择算法函数
chooseAlgorithm();
}
}
void FCFS(){
int i;
//根据到达时间排序
sortArrivalTime();
//FCFS计算第一个进程的时间
pro[0].FinishTime = pro[0].ArrivalTime + pro[0].ServiceTime;
pro[0].WholeTime = pro[0].FinishTime- pro[0].ArrivalTime;
pro[0].WeightWholeTime = pro[0].WholeTime/pro[0].ServiceTime;
pro[0].StartTime = pro[0].ArrivalTime;
//计算每个进程的时间
for(i=1;i<n;i++) {
getTime(i);
SumWT_FCFS += pro[i].WholeTime;
SumWWT_FCFS += pro[i].WeightWholeTime;
}
SumWT_FCFS += pro[0].WholeTime;
SumWWT_FCFS += pro[0].WeightWholeTime;
AverageWT_FCFS =SumWT_FCFS/n;
AverageWWT_FCFS = SumWWT_FCFS/n;
//输出各时间
cout<<"ID"<<"\t"<<"到达时间"<<"\t"<<"服务时间"<<"\t"<<"完成时间"<<"\t"<<"周转时间"<<"\t"<<"带权周转时间"<<endl;
for(i=0;i<n;i++) {
cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t"<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<endl;
};
cout<<"FCFS平均周转时间: "<<AverageWT_FCFS<<endl;
cout<<"FCFS带权平均周转时间: "<<AverageWWT_FCFS<<endl;
//FCFS输出各时间状态
outTime(n);
}
void SJF(){
int i;
//根据到达时间排序
sortArrivalTime();
//计算第一个进程的各时间
pro[0].FinishTime = pro[0].ArrivalTime + pro[0].ServiceTime;
pro[0].WholeTime = pro[0].FinishTime- pro[0].ArrivalTime;
pro[0].WeightWholeTime = (double)pro[0].WholeTime/(double)pro[0].ServiceTime;
pro[0].StartTime = pro[0].ArrivalTime;
//计算每个进程的时间
for(i=1;i<n;i++) {
sortServiceTime(i);
getTime(i);
SumWT_SJF += pro[i].WholeTime;
SumWWT_SJF += pro[i].WeightWholeTime;
}
SumWT_SJF += pro[0].WholeTime;
SumWWT_SJF += pro[0].WeightWholeTime;
AverageWT_SJF = SumWT_SJF/n;
AverageWWT_SJF = SumWWT_SJF/n;
//输出各时间
cout<<"ID"<<"\t"<<"到达时间"<<"\t"<<"服务时间"<<"\t"<<"完成时间"<<"\t"<<"周转时间"<<"\t"<<"带权周转时间"<<endl;
for(i=0;i<n;i++) {
cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t"<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<endl;
};
cout<<"SJF平均周转时间: "<<AverageWT_SJF<<endl;
cout<<"SJF带权平均周转时间: "<<AverageWWT_SJF<<endl;
//SJF输出各时间状态
outTime(n);
}
//根据到达时间排序
void sortArrivalTime() {
int i,j;
for(i=0;i<n;i++) {
for(j=i+1;j<n;j++) {
if(pro[i].ArrivalTime > pro[j].ArrivalTime) {
temp = pro[i];
pro[i] = pro[j];
pro[j] = temp;
}
}
}
}
//已到达的进程服务时间排序
void sortServiceTime(int a) {
int i,j;
//进程的到达时间小于上一个进程的完成时间,则其加入到就绪队伍中
for(i=a;i<n;i++) {
if(pro[i].ArrivalTime<= pro[a-1].FinishTime)
pro[i].ServiceTime_SJF = pro[i].ServiceTime;
}
//将就绪队伍中的进程按服务时间进行排序
for(i=a;i<n;i++) {
for(j=i+1;j<n;j++) {
if(pro[i].ServiceTime_SJF>pro[j].ServiceTime_SJF&&pro[i].ServiceTime_SJF!=0&&pro[j].ServiceTime_SJF!=0){
temp=pro[i];
pro[i]=pro[j];
pro[j]= temp;
}
}
}
}
//计算完成时间、周转时间、带权周转时间、开始执行时间
void getTime(int i) {
if(pro[i].ArrivalTime <= pro[i-1].FinishTime) {
pro[i].FinishTime = pro[i-1].FinishTime + pro[i].ServiceTime;
pro[i].StartTime = pro[i-1].FinishTime;
}
else {
pro[i].FinishTime= pro[i].ArrivalTime + pro[i].ServiceTime;
pro[i].StartTime= pro[i].ArrivalTime;
}
pro[i].WholeTime = pro[i].FinishTime - pro[i].ArrivalTime;
pro[i].WeightWholeTime = pro[i].WholeTime/pro[i].ServiceTime;
}
//输出各时间状态
void outTime(int a) {
int i,j;
for(i=0;i<=pro[a-1].FinishTime;i++) {
cout<<"时刻 "<<i<<": ";
for(j=0;j<a;j++) {
if(pro[j].ArrivalTime == i && pro[j].StartTime== i)
cout<<"进程 "<<pro[j].ID<<" 到达并执行, ";
else if(pro[j].ArrivalTime == i)
cout<<"进程 "<<pro[j].ID<<" 到达, ";
else if(pro[j].StartTime == i)
cout<<"进程 "<<pro[j].ID<<" 开始运行, ";
else if(pro[j].FinishTime == i)
cout<<"进程 "<<pro[j].ID<<" 完成, ";
}
cout<<endl;
}
}
```cpp