- 时间片轮算法原理
根据先来先服务的原则,将需要执行的所有进程按照到达时间的大小排成一个升序的序列,每次都给一个进程同样大小的时间片,在这个时间片内如果进程执行结束了,那么把进程从进程队列中删去,如果进程没有结束,那么把该进程停止然后改为等待状态,放到进程队列的尾部,直到所有的进程都已执行完毕
代码如下
#include<iostream>
#include<fstream>
#include<algorithm>
#include<queue>
#define SIZE 5
#define MAX_TIME 999
#define TIME_SLICE 4
using namespace std;
typedef struct
{
// int sign;//标志位,为0表示未执行,为1表示执行完毕
int trueServTime;//确切的当时服务时间
char name;//进程名字
int ArrivalTime;//到达时间
int ServiceTime;//服务时间
int FinishedTime;//结束时间
int WholeTime;//周转时间 FinishedTime = ArrivalTime
double WeightWholeTime;//带权周转时间 WholeTime/ServiceTime
}RR;
bool Cpare(const RR &a,const RR &b){
return a.ArrivalTime < b.ArrivalTime;
}
static RR R[SIZE];
static queue<RR> RRqueue;
double avgWholeTime=0;
double avgWeightWholeTime=0;
//初始化将进程的名字,到达时间,服务时间输入。定义结束时间,周转时间和带权周转时间为MAX_TIME
void init(){
ifstream ifs;
ifs.open("input.txt");
for(int i=0;i<SIZE;++i){
// R[i].sign = 0;
R[i].trueServTime = 0;
R[i].FinishedTime=MAX_TIME;
R[i].WholeTime=MAX_TIME;
R[i].WeightWholeTime=MAX_TIME;
}
for(int i=0;i<SIZE;++i){
ifs>>R[i].name>>R[i].ArrivalTime>>R[i].ServiceTime;
}
}
//打印结果
void display(){
ofstream ofs;
ofs.open("output.txt");
ofs<<"时间片:"<<TIME_SLICE<<endl;
for(int i=0;i<SIZE;++i){
ofs<<"进程名"<<R[i].name<<endl;
ofs<<" 到达时间"<<R[i].ArrivalTime<<endl;
ofs<<" 服务时间"<<R[i].ServiceTime<<endl;
ofs<<" 完成时间"<<R[i].FinishedTime<<endl;
ofs<<" 周转时间"<<R[i].WholeTime<<endl;
ofs<<" 带权周转时间"<<R[i].WeightWholeTime<<endl;
}
ofs<<endl;
ofs<<"平均周转时间:"<<avgWholeTime<<endl;
ofs<<"带权平均周转时间:"<<avgWeightWholeTime<<endl;
}
//时间轮调度算法
void RRAlgorithm(){
int time = 0;
sort(R,R+SIZE,Cpare);
for(int i=0;i<SIZE;++i){
RRqueue.push(R[i]);
}
int index=0;
while(true){
if(RRqueue.empty()) break;
RR nowRun = RRqueue.front();
if(nowRun.trueServTime + TIME_SLICE >= nowRun.ServiceTime){
time += nowRun.ServiceTime - nowRun.trueServTime;
nowRun.trueServTime = nowRun.ServiceTime;
nowRun.FinishedTime = time;
R[index++] = nowRun;
RRqueue.pop();
}else{
time+=TIME_SLICE;
nowRun.trueServTime+=TIME_SLICE;
RRqueue.pop();
RRqueue.push(nowRun);
}
}
for(int i=0;i<SIZE;++i){
R[i].WholeTime = R[i].FinishedTime - R[i].ArrivalTime;
R[i].WeightWholeTime = (double)R[i].WholeTime/R[i].ServiceTime;
}
sort(R,R+SIZE,Cpare);
for(int i=0;i<SIZE;++i){
avgWholeTime+=R[i].WholeTime;
avgWeightWholeTime+=R[i].WeightWholeTime;
}
avgWholeTime/=SIZE;
avgWeightWholeTime/=SIZE;
}
int main(){
init();
RRAlgorithm();
display();
return 0;
}
小结
这次实验主要是让我们了解操作系统中的进程了解,在进程管理中,进程调度是核心,对于不同的情况要用不同的算法实现,有时候用短作业好的情况不见得换了环境还一样使用,所以对于不同的情况还是用不同的进程调度会更好。时间片来说轮转法是让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。就是按我们通俗来说就是大家都公平,但是时间片大小的控制也很重要,时间片小了时间虽然少了,但是进程切换花费的时间相对就多,时间片大时候恰恰相反。所以现在操作系统很多采用多值时间片。
本实验中的RR算法的时间片大小固定,所以实际是属于基本轮转法,还有种是时间片长短是变化的,即改进轮转法。在基本轮转法中,时间片大小的设置是关键。时间片设得太短会导致过多的进程切换,降低了CPU效率;而设得太长又可能引起对短的交互请求的响应变差。据悉,通常,时间片的长度为几十毫秒到几百毫秒,而将时间片设为100毫秒通常是一个比较合理的折衷。
本文详细解读了时间片轮转算法的工作原理,通过C++代码演示其操作过程,并讨论了时间片大小对调度效率的影响,介绍了基本轮转法与改进轮转法的区别。重点强调了在操作系统中如何根据任务特性选择合适的调度算法。


被折叠的 条评论
为什么被折叠?



