- 实验目的
通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。
- 实验内容
问题描述:
设计程序模拟进程的时间片轮转RR调度过程。假设有n个进程分别在T1, … ,Tn时刻到达系统,它们需要的服务时间分别为S1, … ,Sn。分别利用不同的时间片大小q,采用时间片轮转RR进程调度算法进行调度,计算每个进程的完成时间、周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
程序要求:
1)进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;输入时间片大小q。
2)要求时间片轮转法RR调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;
3)输出:要求模拟整个调度过程,输出每个时刻的进程运行状态,如“时刻3:进程B开始运行”等等;
4)输出:要求输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
实现提示:
用C++语言实现提示:
1)程序中进程调度时间变量描述如下:
int ArrivalTime[100];
int ServiceTime[100];
int PServiceTime[100];
int FinishTime[100];
int WholeTime[100];
double WeightWholeTime[100];
double AverageWT,AverageWWT;
bool Finished[100];
2)进程调度的实现过程如下:
- 变量初始化;
- 接收用户输入n,T1, … ,Tn,S1, … ,Sn;时间片大小q;
- 按照时间片轮转RR算法进行进程调度,计算进程的完成时间、周转时间和带权周转时间;
- 计算所有进程的平均周转时间和平均带权周转时间;
- 按格式输出调度结果。
实验要求:
1)上机前认真复习时间片轮转RR进程调度调度算法,熟悉进程调度的执行过程;
2)上机时独立编程、调试程序;
3)根据具体实验要求,完成好实验报告(包括实验的目的、内容、要求、源程序、实例运行结果截图、发现的问题以及解决方法)
- 实验开发环境
CodeBlocks编译器
- 程序主要构成部分及其算法说明
#include <iostream>
#include <iomanip>
#define MaxNum 100
using namespace std;
char Process[MaxNum] = {'A','B','C','D','E'};
int ArrivalTime[MaxNum]= {0,1,2,3,4}; //到达时间
int ServiceTime[MaxNum]= {4,3,5,2,4}; //服务时间
int ServiceTime1[MaxNum]= {4,3,5,2,4};
int FinishTime[MaxNum]; //完成时间
int WholeTime[MaxNum]; //周转时间
int isProcess[MaxNum]; //P服务时间
int p; //时间片
static int n=5; //进程数
double WeightWholeTime[MaxNum]; //带权周转时间
double AverageWT; //平均周转时间
double AverageWWT; //平均带权周转时间
bool Finished[MaxNum]; //进程是否完成
void Initial() //进行初始化
{
for (int i=0; i<n; i++)
{
p=0;
FinishTime[i] = 0;
WholeTime[i] = 0;
WeightWholeTime[i] = 0;
AverageWT = 0;
AverageWWT = 0;
Finished[i] = false;
}
}
void input()
{
cout<<"请输入时间片p:";
cin>>p;
cout<<endl;
//输出用户输入的信息
cout<<"用户输入的进程个数n="<<n<<endl;
cout<<"用户输入的到达时间分别为:"<<endl;
for (int i=0; i<n; i++)
{
cout<<ArrivalTime[i]<<" ";
}
cout<<endl;
cout<<"用户输入的服务时间分别为:"<<endl;
for (int i=0; i<n; i++)
{
cout<<ServiceTime[i]<<" ";
}
cout<<endl;
cout<<"用户输入的时间片p为:"<<p<<endl;
cout<<endl;
cout<<endl;
}
//输出结果
void result()
{
cout<<endl;
cout<<setw(10)<<"进程名"<<" ";
cout<<setw(10)<<"到达时间"<<" ";
cout<<setw(10)<<"服务时间"<<" ";
cout<<setw(10)<<"完成时间"<<" ";
cout<<setw(10)<<"周转时间"<<" ";
cout<<setw(10)<<"带权周转时间"<<endl;
for (int i = 0; i<n; i++)
{
cout<<setw(10)<<i+1<<" ";
cout<<setw(10)<<ArrivalTime[i]<<" ";
cout<<setw(10)<<ServiceTime1[i]<<" ";
cout<<setw(10)<<FinishTime[i]<<" ";
cout<<setw(10)<<WholeTime[i]<<" ";
cout<<setw(10)<<WeightWholeTime[i]<<" "<<endl;
}
}
void RR()
{
int totalTime = 0; //已经服务的时间
int time = 0; //保存初始时间
isProcess[0]=0; //保存进程数
int tail=0;
int i=1; //寻找未加入的进程
int a=0; //总进程数
while(a!=100)
{
int b=isProcess[a];
if(ServiceTime[b]<=p)
{
time = totalTime;
totalTime+=ServiceTime[b];
ServiceTime[b]=0;
cout<<"时刻"<<time<<"-->"<<"时刻"<<totalTime<<" "<<Process[b]<<endl;
for(int j=i; j<n; j++)
{
if(totalTime>=ArrivalTime[j])
{
isProcess[tail+1]= j;
tail++;
i++;
}
}
if(ServiceTime[b]==0)
{
FinishTime[b]=totalTime;
WholeTime[b]=FinishTime[b]-ArrivalTime[b]; //周转时间=完成时间-到达时间
WeightWholeTime[b]=(double)WholeTime[b]/ServiceTime1[b]; //带权周转时间=周转时间/服务时间
}
}
else
{
time = totalTime;
totalTime=totalTime+p;
ServiceTime[b]=ServiceTime[b]-p; //每运行一次减掉时间p
cout<<"时刻"<<time<<"-->"<<"时刻"<<totalTime<<" "<<Process[b]<<endl;
for(int j=i; j<n; j++)
{
if(totalTime>=ArrivalTime[j])
{
isProcess[tail+1]= j;
tail++;
i++;
}
}
if(ServiceTime[b]>0)
{
isProcess[tail+1]=b;
tail++;
}
if(ServiceTime[b]==0)
{
FinishTime[b]=totalTime;
WholeTime[b]=FinishTime[b]-ArrivalTime[b]; //周转时间=完成时间-到达时间
WeightWholeTime[b]=double(WholeTime[b])/ServiceTime1[b]; //带权周转时间=周转时间/服务时间
}
}
if(a<tail)
{
a++;
}
else
{
break;
}
}
result();
//计算平均周转时间和平均带权周转时间
double totalWT = 0;
double totalWWT = 0;
for (int i=0; i<tail; i++)
{
totalWT+=WholeTime[i];
totalWWT+=WeightWholeTime[i];
}
AverageWT = totalWT/n; //平均周转时间=周转时间之和/进程数n
AverageWWT = totalWWT/n; //平均带权周转时间=带权周转时间/进程数n
cout<<"平均周转时间为:"<<AverageWT<<endl;
cout<<"平均带权周转时间为:"<<AverageWWT<<endl;
}
int main()
{
Initial();
input();
RR();
return 0;
}
算法分为对数组初始化Initial(),然后给时间片赋值input(),然后RR()方法进行计算得到每个时间段的进程运行状态以及每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
RR核心算法如下:
void RR()
{
int totalTime = 0; //已经服务的时间
int time = 0; //保存初始时间
isProcess[0]=0; //保存进程数
int tail=0;
int i=1; //寻找未加入的进程
int a=0; //总进程数
while(a!=100)
{
int b=isProcess[a];
if(ServiceTime[b]<=p)
{
time = totalTime;
totalTime+=ServiceTime[b];
ServiceTime[b]=0;
cout<<"时刻"<<time<<"-->"<<"时刻"<<totalTime<<" "<<Process[b]<<endl;
for(int j=i; j<n; j++)
{
if(totalTime>=ArrivalTime[j])
{
isProcess[tail+1]= j;
tail++;
i++;
}
}
if(ServiceTime[b]==0)
{
FinishTime[b]=totalTime;
WholeTime[b]=FinishTime[b]-ArrivalTime[b]; //周转时间=完成时间-到达时间
WeightWholeTime[b]=(double)WholeTime[b]/ServiceTime1[b]; //带权周转时间=周转时间/服务时间
}
}
else
{
time = totalTime;
totalTime=totalTime+p;
ServiceTime[b]=ServiceTime[b]-p; //每运行一次减掉时间p
cout<<"时刻"<<time<<"-->"<<"时刻"<<totalTime<<" "<<Process[b]<<endl;
for(int j=i; j<n; j++)
{
if(totalTime>=ArrivalTime[j])
{
isProcess[tail+1]= j;
tail++;
i++;
}
}
if(ServiceTime[b]>0)
{
isProcess[tail+1]=b;
tail++;
}
if(ServiceTime[b]==0)
{
FinishTime[b]=totalTime;
WholeTime[b]=FinishTime[b]-ArrivalTime[b]; //周转时间=完成时间-到达时间
WeightWholeTime[b]=double(WholeTime[b])/ServiceTime1[b]; //带权周转时间=周转时间/服务时间
}
}
if(a<tail)
{
a++;
}
else
{
break;
}
}
result();
//计算平均周转时间和平均带权周转时间
double totalWT = 0;
double totalWWT = 0;
for (int i=0; i<tail; i++)
{
totalWT+=WholeTime[i];
totalWWT+=WeightWholeTime[i];
}
AverageWT = totalWT/n; //平均周转时间=周转时间之和/进程数n
AverageWWT = totalWWT/n; //平均带权周转时间=带权周转时间/进程数n
cout<<"平均周转时间为:"<<AverageWT<<endl;
cout<<"平均带权周转时间为:"<<AverageWWT<<endl;
}
通过一个while循环对进程进行循环计算,if语句是通过判断当前进程的剩余的服务时间是否小于时间片的时间如果是则直接表示进程结束,然后总时间加上当前进程的服务时间,再用for对剩余未进行的进程进行遍历,用if语句判断剩余进程的到达时间是否小于总服务时间如果是则将他们放入isProcess[]数组里面,如果第一个if语句通过判断当前进程的剩余的服务时间是否小于时间片的时间不对的话则进入else语句,总时间加上时间片p的时间,然后当前进程的服务时间-p,再用for对剩余未进行的进程进行遍历,用if语句判断剩余进程的到达时间是否小于总服务时间如果是则将他们放入isProcess[]数组里面,然后再判断当前进程的服务时间是否大于0如果是也将它放入isProcess[]数组里面。最后通过判断a是否小于tail,如果不是a++,如何是则while结束!
- 调试过程和运行结果
时间片为1时
时间片为4时