欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > windows >内容正文

windows

操作系统——时间片轮转调度算法(RR)

发布时间:2023/12/20 windows 44 豆豆
生活随笔 收集整理的这篇文章主要介绍了 操作系统——时间片轮转调度算法(RR) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

RR算法总体思路流程图

主要数据结构及参数

typedef struct PCB {char name;//进程名int arrive_time;//到达时间float cpu_burst;//服务时间float surplus;//剩余服务时间int start_time;//开始执行时间int finish_time;//完成时间int wait_time;//等待时间float turn_time;//周转时间float weighted_ttime;//带权周转时间bool over;//标记进程是否执行完毕float response;//响应比 }PCB;//定义进程数据结构int pcb_num;//进程个数int time_p;//时间片大小

主要函数

//将进程按照到达先后顺序排序 void sort_arrival(PCB pcb[],int pcb_num){}//计算周转时间和带权周转时间 void calculator_rr(PCB pcb[],int pcb_num){}//RR调度算法 void rr(PCB pcb[],int pcb_num,float time_p){}//计算平均周转时间、平均带权周转时间、平均等待时间 void cal_avg(PCB pcb[],int pcb_num){}//输出各进程 void show(PCB pcb[],int pcb_num){}//主函数测试RR调度算法 int main(){}

①sort_arrival()函数:输入进程顺序表pcb[]和进程个数pcb_num作为函数参数,然后将顺序表pcb[]按照到达的先后顺序排序。

②calculator_rr()函数:输入进程顺序表pcb[]和进程个数pcb_num作为函数参数,用于在rr()函数中反复调用,根据顺序表pcb[]中已知的到达时间、完成时间、服务时间,计算周转时间和带权周转时间

③rr()函数:输入进程顺序表pcb[]和进程个数pcb_num作为函数参数,主要是实现RR调度算法,将经RR调度算法计算后的开始执行时间、完成时间、等待时间、周转时间、带权周转时间存入进程顺序表中。

④cal_avg()函数:输入进程顺序表pcb[]和进程个数pcb_num作为函数参数,通过进程顺序表中的等待时间、周转时间、带权周转时间计算出平均等待时间、平均周转时间、平均带权周转时间,然后输出。

⑤show()函数:输入进程顺序表pcb[]和进程个数pcb_num作为函数参数,以表格的形式输出进程顺序表中的各参数信息。

⑥main()函数:主函数中输入进程顺序表,测试FCFS调度函数和SJF调度函数,输出测试结果。

代码

#include<iostream> #include<iomanip> #include<queue> #include<algorithm>using namespace std;typedef struct PCB {char name;//进程名int arrive_time;//到达时间float cpu_burst;//服务时间float surplus;//剩余服务时间int start_time;//开始执行时间int finish_time;//完成时间int wait_time;//等待时间float turn_time;//周转时间float weighted_ttime;//带权周转时间bool over;//标记进程是否执行 }PCB;//定义进程数据结构//将进程按照到达先后顺序排序 void sort_arrival(PCB pcb[],int pcb_num) {PCB temp;for(int i=0;i<pcb_num-1;i++){for(int j=i+1;j<pcb_num;j++){if(pcb[i].arrive_time>pcb[j].arrive_time){temp = pcb[i];pcb[i] = pcb[j];pcb[j] = temp;}}} }//计算周转时间和带权周转时间 void calculator_rr(PCB pcb[],int pcb_num) {for(int i=0;i<pcb_num;i++){pcb[i].turn_time = pcb[i].finish_time-pcb[i].arrive_time;//周转时间 = 完成时间-到达时间pcb[i].weighted_ttime = pcb[i].turn_time/pcb[i].cpu_burst;//带权周转时间 = 周转时间/服务时间} }//RR调度算法 void rr(PCB pcb[],int pcb_num,float time_p) {for(int i=0;i<pcb_num;i++){pcb[i].surplus = pcb[i].cpu_burst;pcb[i].finish_time = 0;pcb[i].start_time = 0;pcb[i].turn_time = 0;pcb[i].wait_time = 0;pcb[i].weighted_ttime = 0;}//初始化进程信息queue<int> wait_q;//定义进程等待队列sort_arrival(pcb,pcb_num);//将所有进程按照到达的先后顺序排列int t = pcb[0].arrive_time;//时间从第一个进程到达开始wait_q.push(0);//将第一个进程加入等待队列while(wait_q.empty() == false){int t0 =t;//记录需要进行进程切换的时刻int run;run = wait_q.front();wait_q.pop();if(pcb[run].over == false)//进程第一次执行时{pcb[run].start_time = t;//记录第一次开始执行的时间pcb[run].wait_time = pcb[run].wait_time+t-pcb[run].arrive_time;//累加计算等待时间pcb[run].over = true;}else//进程非第一次执行时{pcb[run].wait_time = pcb[run].wait_time+t-pcb[run].finish_time;//累加计算等待时间}t = t+min(pcb[run].surplus,time_p);//将时间切换到下个时间片,或进程执行完毕pcb[run].finish_time = t;//更新每次进程执行结束的时间pcb[run].surplus = pcb[run].surplus-min(pcb[run].surplus,time_p);//更新进程剩余服务时间if(t0<pcb[pcb_num-1].arrive_time){for(int i=0;i<pcb_num;i++){if(pcb[i].arrive_time>t0 && pcb[i].arrive_time<=t){wait_q.push(i);}}//将所有在t0-t时间内到达的进程按照到达的先后顺序加入等待队列}if(pcb[run].surplus != 0){wait_q.push(run);//若进程执行完毕则不再加入等待队列}}calculator_rr(pcb,pcb_num);//计算进程周转时间、带权周转时间 }//计算平均周转时间、平均带权周转时间、平均等待时间 void cal_avg(PCB pcb[],int pcb_num) {float sum1 = 0,sum2 = 0, sum3 = 0;float avg_turn, avg_weight, avg_wait;for(int i=0;i<pcb_num;i++){sum1 = sum1+pcb[i].turn_time;sum2 = sum2+pcb[i].weighted_ttime;sum3 = sum3+pcb[i].wait_time;}avg_turn = sum1/pcb_num;avg_weight = sum2/pcb_num;avg_wait = sum3/pcb_num;cout<<"平均周转时间为:"<<avg_turn<<endl;cout<<"平均带权周转时间为:"<<avg_weight<<endl;cout<<"平均等待时间为:"<<avg_wait<<endl; }//输出各进程 void show(PCB pcb[],int pcb_num) {cout<<"-----------------------------------------------------------------------------"<<endl;cout<<"进程名|到达时间|服务时间|开始执行时间|完成时间|周转时间|带权周转时间|等待时间"<<endl;cout<<"-----------------------------------------------------------------------------"<<endl;for(int i=0;i<pcb_num;i++){cout<<pcb[i].name;cout<<"\t"<<pcb[i].arrive_time;cout<<"\t"<<pcb[i].cpu_burst;cout<<"\t"<<"\t"<<pcb[i].start_time;cout<<"\t"<<pcb[i].finish_time;cout<<"\t"<<pcb[i].turn_time;cout<<"\t"<<setprecision(3)<<pcb[i].weighted_ttime;cout<<"\t"<<pcb[i].wait_time<<endl;} }//主函数测试RR调度算法 int main() {int pcb_num;//进程个数cout<<"请输入进程总个数:"<<endl;cin>>pcb_num;PCB pcb[pcb_num];for(int i=0;i<pcb_num;i++){cout<<"请输入进程名:";cin>>pcb[i].name;//输入各进程名cout<<"请输入进程到达时间:";cin>>pcb[i].arrive_time; //输入各进程的到达时间cout<<"请输入进程需要服务的时间:";cin>>pcb[i].cpu_burst; //输入各进程需要服务的时间pcb[i].over = false;//初始时,所有进程执行状态都为falsepcb[i].surplus = pcb[i].cpu_burst;//初始时,所有进程剩余服务时间都为服务时间pcb[i].finish_time = 0;pcb[i].start_time = 0;pcb[i].turn_time = 0;pcb[i].wait_time = 0;pcb[i].weighted_ttime = 0;}cout<<"--------------------------------"<<endl;cout<<" RR调度结果 "<<endl;cout<<"--------------------------------"<<endl;int time_p;//时间片大小bool goon = true;while(goon == true){cout<<"请输入时间片大小:";cin>>time_p;rr(pcb,pcb_num,time_p);show(pcb,pcb_num);cout<<endl;cal_avg(pcb,pcb_num);cout<<"是否继续测试RR调度结果(是则输入1,否则输入0):";cin>>goon;}return 0; }

结果

结果分析

时间片轮转RR调度算法很大程度上取决于时间片大小的选取,时间片的大小直接决定了时间片轮转RR调度算法的效率,时间片选取过小,会频繁发生终端,需要不断进行上下文的切换,严重增加了系统的开销;时间片选取过大则时间片轮转RR调度算法直接退化为先来先服务FCFS调度算法。从表格可以看出,时间片轮转RR调度算法的各参数值都较高,效率较其他算法不算高,而且明显时间片轮转RR调度算法对时间片的选取要求较高,需要实现知道各进程的参数情况才能够选取合适的时间片大小。

总结

以上是生活随笔为你收集整理的操作系统——时间片轮转调度算法(RR)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。