首页 > 编程知识 正文

轮转调度算法告诉我们什么,操作系统轮转调度算法例题

时间:2023-05-06 05:34:25 阅读:182190 作者:2044

情况介绍基本原理系统根据FCFS原则,将所有准备过程排队按顺序调度。 将CPU分配给团队的第一个进程并运行一个时间片(10-100ms )。 使用时间片后,系统计时器发出时钟中断,进程将占用CPU并将其插入就绪队列的末尾。 如果切换的时间片未过期而进程终止,则立即调度准备队列中队列第一个进程的执行,并开始新的时间片。 当一个时间片用完时,如果进程还没有运行,则剥夺CPU,调度程序将其发送到队列的末尾。 参数式的旋转时间=作业完成时间-作业到达时间

授权周转时间=周转时间/服务时间

平均周转时间=作业周转总时间/作业个数

平均周转时间=周转总时间/工作个数。

注意事项3http://www.Sina.com//http://www.Sina.com/http://www.Sina.com /、红框的权利周转时间应该是错误的,e的权利周转时间是3358 www.Sina.com

要模拟拔模进程的执行:

队列执行情况:

具体来说,就是实现对新进程进行排队的排队c代码。

# include cstdio # include cstring # include iostream # include algorithm # include vector # includequeueusingnamespacestd; struct PCB {int id; //进程编号char name; //进程名称int arrive; //到达时间int serve; //服务时间int finish; //完成时间//优先参考到达时间,然后服务时间booloperator(constPCBt ) const ) if ) arrive!=t.arrive(returnarrivet.arrive; return serve t.serve; (; (; const int N=10; //最多10个进程const int M=100; //最多100小时单位PCB pcb_list[N]; //进程列表vectorPCB table[M]; //进程调度queuePCB que; //进程队列int n,t,q,sjp; //进程数、合计时间、固定时间片、运行时间片int max_time; //最大时间void query ()//查询当前进程是否已到达,如果有,则将入队//当前时间的所有进程入队的for(intI=0); i table[t].size (; I ) que.push(table[t][I]; }voidrun((cout )当前时间(t ) )运行进程(t ) )剩余服务时间) endl; PCB cur=pcb_list[0]; //初始化当前进程的sjp=q; //初始化时间片for (t=0; t=max_time; t ()//跑步时间query ) ); //当前进程是否到达,如果有,则入队if(que.empty ) ) continue; //队列空闲时,跳过if (sjp||! cur.serve(//如果时间片已丢失或当前进程已完成,则sjp=q; //恢复时间片que.pop (; //团队的第一个团队if(cur.serve ) que.push ) cur; //如果当前进程未运行,则返回队列末尾的else pcb_list[cur.id].finish=t; //运转结束,设定完成时刻if (! que.empty () (cur=que.front ); //取得新团队领导的else continue; //已经空了。 } coutt 'tt ' cur.name 'tt ' cur.serve endl; //当前时间的状态sjp--,cur.serve--; //时间间隔-1,当前进程服务时间-1 }}void set_max_time () ) for(intI=0; i n; I ) max_time =pcb_list[i].serve; max_time=5; //稍微多避免边界问题(删除也没关系。 程序已经准备好了) }int main ) ) {printf ) (时间片的轮转调度算法(n(n ) ) ) ) )时间片的轮转调度算法(n(n ) ) ) n )”cin n q; //输入进程数和时间片时间printf ('请输入每个进程的进程名称到达时间服务时间n ); for(intI=0; i n; I ) CIN PCB _ list [ I ].name PCB _ list [ I ].arrive PCB _ list [ I ].serve;

sort(pcb_list,pcb_list+n);//对进程按到达时间排序for(int i = 0; i < n; i++) {pcb_list[i].id = i;//给进程编号 table[pcb_list[i].arrive].push_back(pcb_list[i]);//将进程送到时刻表 }set_max_time();//设置最大运行时间run();//开始运行cout << "进程名字t" << "完成时间t" << "周转时间t" << "带权周转时间" << endl;for(int i = 0; i < n; i++) {int zzsj = pcb_list[i].finish-pcb_list[i].arrive;double dqzzsj = (double)zzsj / pcb_list[i].serve;printf("%ctt%dtt%dtt%.2lfn",pcb_list[i].name,pcb_list[i].finish,zzsj,dqzzsj);}return 0;}

说明:

如果不用table来记录每个时间点上的新进程,也可以query的时候遍历一遍pcb_list。

时间片为1的时候

运行效果:

与草稿纸上模拟的一致

时间片为4的时候

运行效果:

与草稿纸上模拟的一致

将新进程放在队列的队首

C++代码

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <deque>using namespace std;struct PCB {int id;//进程编号 char name;//进程名字int arrive;//到达时间int serve;//服务时间int finish;//完成时刻//排序优先参考到达时间,其次是服务时间 bool operator< (const PCB &t) const{if(arrive != t.arrive) return arrive < t.arrive;return serve < t.serve;};};const int N = 10;//最多10个进程const int M = 100;//最长100个时间单位 PCB pcb_list[N];//进程列表vector<PCB> table[M];//进程时刻表deque<PCB> que;//进程队列int n,t,q,sjp;//进程数,总计时,固定时间片,运转时间片int max_time;//最大时间void query() {//查询当前是否有进程到达,有则入队//将当前时刻的所有进程入队for(int i = 0; i < table[t].size(); i++)que.push_front(table[t][i]);}void run() {cout << "当前时刻t" << "运行进程t" << "剩余服务时间" << endl;PCB cur = pcb_list[0];//初始化当前进程sjp = q;//初始化时间片 for(t = 0; t <= max_time; t++) {//跑时间//记录队列中队首的进程deque<PCB>::iterator it;it = que.begin();query();//当前是否有进程到达,有则入队if(que.empty()) continue;//如果队列空,跳过if(!sjp || !cur.serve) {//时间片用完了 或 当前进程运行完了,则调度 sjp = q;//恢复时间片que.erase(it);//删除之前记录的进程(相当于把那个进程出队) if(cur.serve) que.push_back(cur);//如果当前进程没有运行完,则移到队尾else pcb_list[cur.id].finish = t;//运行完了,设置完成时刻 if(!que.empty()) cur = que.front();//取新的队首else continue;//已经空了,跳过 }cout << t << "tt" << cur.name << "tt" << cur.serve << endl;//输出当前时刻状态 sjp--,cur.serve--;//时间片-1,当前进程服务时间-1 }}void set_max_time() {for(int i = 0; i < n; i++) {max_time += pcb_list[i].serve;}max_time+=5;//多加一点避免边界问题(删掉也没关系,程序已经很完备了) }int main() {printf("时间片轮转调度算法nn");printf("请输入进程数 时间片n");cin >> n >> q;//输入进程数和时间片时长printf("请输入每个进程的进程名 到达时间 服务时间n");for(int i = 0; i < n; i++)cin >> pcb_list[i].name >> pcb_list[i].arrive >> pcb_list[i].serve;sort(pcb_list,pcb_list+n);//对进程按到达时间排序for(int i = 0; i < n; i++) {pcb_list[i].id = i;//给进程编号 table[pcb_list[i].arrive].push_back(pcb_list[i]);//将进程送到时刻表 }set_max_time();//设置最大运行时间run();//开始运行cout << "进程名字t" << "完成时间t" << "周转时间t" << "带权周转时间" << endl;for(int i = 0; i < n; i++) {int zzsj = pcb_list[i].finish-pcb_list[i].arrive;double dqzzsj = (double)zzsj / pcb_list[i].serve;printf("%ctt%dtt%dtt%.2lfn",pcb_list[i].name,pcb_list[i].finish,zzsj,dqzzsj);}return 0;}

说明:

由于新进程要放在队首,所以要用双向队列的容器deque。由于新进程放在队首,所以原队首容易找不到,所以要用迭代器记录一下原来队首的进程,方便把它出队。

时间片为1的时候

运行效果:

与草稿纸上模拟一致

时间片为4的时候,放队首和队尾的效果是一样的,就不重复展示了。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。