当前位置:文档之家› 时间片轮转调度算法实验报告

时间片轮转调度算法实验报告

xx大学操作系统实验报告姓名:学号:班级:实验日期:实验名称:时间片轮转RR进程调度算法实验二时间片轮转RR进程调度算法1.实验目的:通过这次实验,理解时间片轮转RR进程调度算法的运行原理,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。

2.需求分析(1) 输入的形式和输入值的范围;输入:进程个数n 范围:0<n<=100时间片q依次输入(进程名进程到达时间进程服务时间)所有进程平均周转时间:所有进程平均带权周转时间:(3) 程序所能达到的功能1)进程个数n,输入时间片大小q,每个进程的到达时间T1, … ,T n和服务时间S1, … ,S n。

2)要求时间片轮转法RR调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;3)输出:模拟整个调度过程,输出每个时刻的进程运行状态;4)输出:输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。

(4) 测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果。

正确输入:错误输入:2、概要设计所有抽象数据类型的定义:static int MaxNum=100int ArrivalTime //到达时间int ServiceTime //服务时间int FinishedTime //结束时间int WholeTime //周转时间double WeightWholeTime //带权周转时间double AverageWT //平均周转时间double AverageWWT //平均带权周转时间主程序的流程:变量初始化●接受用户输入的n,q ,T1…..Tn, S1….Sn;●进行进程调度,计算进程的开始运行时间、结束时间、执行顺序、周转时间、带权周转时间;●计算所有进程的平均周转时间、平均带权周转时间;●按照格式输出调度结果。

各程序模块之间的层次(调用)关系Main函数通过对Input函数进行调用,对函数的成员变量进行赋值,再通过RRAlgorithm函数求出题目要求的各个数据结果,最后通过display函数对结果进行格式输出。

3、详细设计实现程序模块的具体算法。

void RRAlgorithm(){char processMoment[100]; //存储每个时间片p对应的进程名称RRqueue.push(RRarray[0]);int processMomentPoint = 0;int CurrentTime=0;int tempTime; //声明此变量控制CurrentTime的累加时间,当前进程的服务时间小于时间片q的时候,起到重要作用int i=1; //指向还未处理的进程的下标int finalProcessNumber = 0; //执行RR算法后,进程的个数int processTime[50];//CurrentTime的初始化if (RRarray[0].ServiceTime>=q){CurrentTime = q;}else{CurrentTime = RRarray[0].ServiceTime;}while(!RRqueue.empty()){for (int j=i;j<n;j++) //使得满足进程的到达时间小于当前时间的进程都进入队列{if (RRarray[j].name!=NULL && CurrentTime >= RRarray[j].ArrivalTime){RRqueue.push(RRarray[j]);i++;}}if (RRqueue.front().ServiceTime<q){tempTime = RRqueue.front().ServiceTime;}else{tempTime = q;}RRqueue.front().ServiceTime -= q; //进程每执行一次,就将其服务时间-q//将队首进程的名称放入数组中processMoment[processMomentPoint] = RRqueue.front().name;processMomentPoint++;processTime[finalProcessNumber] = tempTime;finalProcessNumber++;if (RRqueue.front().ServiceTime <= 0) //把执行完的进程退出队列{//RRqueue.front().FinishedTime = CurrentTime;RRqueue.pop(); //如果进程的服务时间小于等于,即该进程已经服务完了,将其退栈}else{//将队首移到队尾RRqueue.push(RRqueue.front());RRqueue.pop();}CurrentTime += tempTime;}//进程输出处理每个时间段对应的执行的进程cout<<"各进程的执行时刻信息:"<<endl;cout<<" "<<"0时刻--> "<<setw(2)<<processTime[0]<<"时刻";processTime[finalProcessNumber]=0;int time = processTime[0];int count = 0;for (i=0;i<finalProcessNumber;i++){count = 0;cout<<setw(3)<<processMoment[i]<<setw(3)<<endl;while(RRarray[count].name!=processMoment[i] && count<n){count++;}RRarray[count].FinishedTime = time;if (i<finalProcessNumber - 1){cout<<setw(3)<<time<<"时刻"<<" --> "<<setw(2)<<time + processTime[i+1]<<"时刻"<<setw(3);time += processTime[i+1];}}cout<<endl;//周转时间、带权周转时间、平均周转时间、带权平均周转时间的计算//1. 周转时间= 完成时间- 到达时间//2. 带权周转时间= 周转时间/服务时间for ( i=0;i<n;i++){RRarray[i].WholeTime = RRarray[i].FinishedTime - RRarray[i].ArrivalTime;RRarray[i].WeightWholeTime = (double)RRarray[i].WholeTime/RRarray[i].ServiceTime;}double x=0,y=0;for (i=0;i<n;i++){x += RRarray[i].WholeTime;y += RRarray[i].WeightWholeTime;}AverageWT = x/n;AverageWWT = y/n;}4、调试分析(1)调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析在算法设计时,由于一开始不知道如何将位于队首的进程,在执行完后如何移至队尾进行循环,所以思考了很久,后来想到将队首进程进行重新压入队列从而解决了此问题。

(2)算法的性能分析每个进程被分配一个时间段,即该进程允许运行的时间。

如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。

如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。

调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。

(3)经验体会通过本次实验,深入理解了时间片轮转RR进程调度算法的思想,培养了自己的动手能力,通过实践加深了记忆。

5、用户使用说明程序的使用说明,列出每一步的操作步骤。

7、附录带注释的源程序,注释应清楚具体#include <iostream>#include <queue>#include <iomanip>#include <fstream>#define MaxNum 100using namespace std;typedef struct{char name;int ArrivalTime;int ServiceTime;int FinishedTime;int WholeTime;double WeightWholeTime;}RR;static queue<RR>RRqueue; //声明一个队列static double AverageWT =0,AverageWWT=0; static int q; //时间片static int n; //进程个数static RR RRarray[MaxNum]; //进程结构void Input(){//文件读取模式ifstream inData;inData.open("./data4.txt");//data.txt表示q = 4的RR调度算法//data2.txt表示q = 1的RR调度算法inData>>n;inData>>q;for (int i=0;i<n;i++){inData>>RRarray[i].name;}for (i=0;i<n;i++){inData>>RRarray[i].ArrivalTime;}for (i=0;i<n;i++){inData>>RRarray[i].ServiceTime;}//用户输入模式cout<<"************************************************************** **"<<endl;cout<<"请输入进程个数n :";cin>>n;cout<<"请输入时间片q :";cin>>q;cout<<"请按到达时间的顺序依次输入进程名:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].name;}cout<<"请从小到大输入进程到达时间:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].ArrivalTime;}cout<<"请按到达时间的顺序依次输入进程服务时间:"<<endl;for (i=0;i<n;i++){cin>>RRarray[i].ServiceTime;}cout<<"************************************************************** **"<<endl;//输出用户所输入的信息cout<<"The information of processes is the following:"<<endl;cout<<setw(10)<<"进程名"<<" ";cout<<setw(10)<<"到达时间"<<" ";cout<<setw(10)<<"服务时间"<<" "<<endl;for ( i=0;i<n;i++){cout<<setw(10)<<RRarray[i].name<<" ";cout<<setw(10)<<RRarray[i].ArrivalTime<<" ";cout<<setw(10)<<RRarray[i].ServiceTime<<" "<<endl;}cout<<"************************************************************** **"<<endl;}void RRAlgorithm(){char processMoment[100]; //存储每个时间片p对应的进程名称RRqueue.push(RRarray[0]);int processMomentPoint = 0;int CurrentTime=0;int tempTime; //声明此变量控制CurrentTime的累加时间,当前进程的服务时间小于时间片q的时候,起到重要作用int i=1; //指向还未处理的进程的下标int finalProcessNumber = 0; //执行RR算法后,进程的个数int processTime[50];//CurrentTime的初始化if (RRarray[0].ServiceTime>=q){CurrentTime = q;}else{CurrentTime = RRarray[0].ServiceTime;}while(!RRqueue.empty()){for (int j=i;j<n;j++) //使得满足进程的到达时间小于当前时间的进程都进入队列{if (RRarray[j].name!=NULL && CurrentTime >= RRarray[j].ArrivalTime){RRqueue.push(RRarray[j]);i++;}}if (RRqueue.front().ServiceTime<q){tempTime = RRqueue.front().ServiceTime;}else{tempTime = q;}RRqueue.front().ServiceTime -= q; //进程每执行一次,就将其服务时间-q//将队首进程的名称放入数组中processMoment[processMomentPoint] = RRqueue.front().name;processMomentPoint++;processTime[finalProcessNumber] = tempTime;finalProcessNumber++;if (RRqueue.front().ServiceTime <= 0) //把执行完的进程退出队列{//RRqueue.front().FinishedTime = CurrentTime;RRqueue.pop(); //如果进程的服务时间小于等于,即该进程已经服务完了,将其退栈}else{//将队首移到队尾RRqueue.push(RRqueue.front());RRqueue.pop();}CurrentTime += tempTime;}//进程输出处理每个时间段对应的执行的进程cout<<"各进程的执行时刻信息:"<<endl;cout<<" "<<"0时刻--> "<<setw(2)<<processTime[0]<<"时刻";processTime[finalProcessNumber]=0;int time = processTime[0];int count = 0;for (i=0;i<finalProcessNumber;i++){count = 0;cout<<setw(3)<<processMoment[i]<<setw(3)<<endl;while(RRarray[count].name!=processMoment[i] && count<n){count++;}RRarray[count].FinishedTime = time;if (i<finalProcessNumber - 1){cout<<setw(3)<<time<<"时刻"<<" --> "<<setw(2)<<time + processTime[i+1]<<"时刻"<<setw(3);time += processTime[i+1];}}cout<<endl;//周转时间、带权周转时间、平均周转时间、带权平均周转时间的计算//1. 周转时间= 完成时间- 到达时间//2. 带权周转时间= 周转时间/服务时间for ( i=0;i<n;i++){RRarray[i].WholeTime = RRarray[i].FinishedTime - RRarray[i].ArrivalTime;RRarray[i].WeightWholeTime = (double)RRarray[i].WholeTime/RRarray[i].ServiceTime;}double x=0,y=0;for (i=0;i<n;i++){x += RRarray[i].WholeTime;y += RRarray[i].WeightWholeTime;}AverageWT = x/n;AverageWWT = y/n;}void display(){cout<<"******************************************************"<<endl;cout<<"RR调度算法执行后:进程相关信息如下:"<<endl;cout<<setw(10)<<"进程名(ID)"<<" ";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)<<RRarray[i].name<<" ";cout<<setw(10)<<RRarray[i].ArrivalTime<<" ";cout<<setw(10)<<RRarray[i].ServiceTime<<" ";cout<<setw(10)<<RRarray[i].FinishedTime<<" ";cout<<setw(10)<<RRarray[i].WholeTime<<" ";cout<<setw(10)<<RRarray[i].WeightWholeTime<<" "<<endl;;}cout<<"所有进程的平均周转时间= "<<AverageWT<<endl;cout<<"所有进程的平均带权周转时间= "<<AverageWWT<<endl;cout<<"******************************************************"<<endl; }int main(){Input();RRAlgorithm();display();return 0;}。

相关主题