操作系统实验二——时间片轮转调度算法(RR算法)(新进程放队首和队尾两种C++实现)
情况介绍
基本原理
- 系统将所有就绪进程按照FCFS的原则,排成一个队列依次调度。
- 把CPU分配给队首进程,执行一个时间片(10-100ms)。
- 时间片用完后,系统计时器发出时钟中断,该进程将被剥夺CPU并插入就绪队列末尾。
切换时机
- 若时间片没有用完,进程就结束,那么立即调度就绪队列中的队首进程运行,并启动一个新的时间片。
- 如果在一个时间片用完时,进程尚未运行完毕,则剥夺CPU,调度程序把它送往队列的末尾。
参数公式
周转时间=作业完成时刻-作业到达时刻;
带权周转时间=周转时间/服务时间;
平均周转时间=作业周转总时间/作业个数;
平均带权周转时间=带权周转总时间/作业个数。
注意事项
- 时间片结束的时候,如果有新进程到来,先进队列,再将当前移到队尾
- 新进程进队列有两种方式,一种是进队列的队尾,一种是进队列的队首。
书上的表格是使用新进程放队首的效果,注意红框的带权周转时间应该算错了,E的带权周转时间应为3.25。
模拟草稿
进程执行情况:
队列执行情况:
具体实现
将新进程放在队列的队尾
C++代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
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]; //进程时刻表
queue<PCB> que; //进程队列
int n,t,q,sjp; //进程数,总计时,固定时间片,运转时间片
int max_time; //最大时间
void query() { //查询当前是否有进程到达,有则入队//将当前时刻的所有进程入队for(int i = 0; i < table[t].size(); i++)que.push(table[t][i]);
}
void run() {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; //已经空了,跳过 }cout << t << "\t\t" << cur.name << "\t\t" << 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("时间片轮转调度算法\n\n");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("%c\t\t%d\t\t%d\t\t%.2lf\n",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 << "\t\t" << cur.name << "\t\t" << 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("时间片轮转调度算法\n\n");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("%c\t\t%d\t\t%d\t\t%.2lf\n",pcb_list[i].name,pcb_list[i].finish,zzsj,dqzzsj);}return 0;
}
说明:
- 由于新进程要放在队首,所以要用双向队列的容器deque。
- 由于新进程放在队首,所以原队首容易找不到,所以要用迭代器记录一下原来队首的进程,方便把它出队。
时间片为1的时候
运行效果:
与草稿纸上模拟一致
时间片为4的时候,放队首和队尾的效果是一样的,就不重复展示了。
操作系统实验二——时间片轮转调度算法(RR算法)(新进程放队首和队尾两种C++实现)相关推荐
- 操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)
实验二 进程调度 一. 实验目的 1. 理解进程运行的并发性. 2. 理解处理器的三级调度. 3. 掌握先来先服务的进程调度算法. 4. 掌握短 ...
- 操作系统实验二——进程调度算法(FCFS、RR)
目录 进程调度算法 FCFS算法代码 RR算法代码 进程调度算法 FCFS算法代码 #include <stdio.h> #include <string.h> #includ ...
- 广州大学2020操作系统实验二:银行家算法
相关资料 广州大学2020操作系统实验一:进程管理与进程通信 广州大学2020操作系统实验二:银行家算法 广州大学2020操作系统实验三:内存管理 广州大学2020操作系统实验四:文件系统 广州大学2 ...
- 操作系统实验二:物理内存管理系统
操作系统实验二:物理内存管理系统 一. 实验目的 二. 实验内容 三. 实验准备 [实验概述] [关键数据结构] [执行流程] 四. 实验步骤 (一) 练习0:填写已有实验 (二) 练习1:实现 fi ...
- C语言实现操作系统的进程调度算法--RR算法
c语言实现调度算法--RR算法 测试输入为4个进程,时间片q=3,进程为A.B.C.D,序列号为都为0,运行时间分别为6/7/9/12 测试输入为4个进程,时间片q=3,进程为A.B.C.D,序列号为 ...
- 操作系统实验1—实现单处理机下的进程调度程序
操作系统实验1-实现单处理机下的进程调度程序 文章目录 操作系统实验1-实现单处理机下的进程调度程序 实验描述 设计思路 上机代码 测试结果 心得体会 实验描述 实验内容: 编写一个单处理机下的进程调 ...
- 实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
贺邦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的: 使用库函数 ...
- ML之catboost:基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两种方式)
ML之catboost:基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两种方式) 目录 基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两 ...
- 操作系统|时间片轮转调度算法(RR)
模拟实现非抢占式 将进程信息表的信息根据进入时间排序,判断当前时间线下有哪些进程到达,将其插入到等待队列中,等待分配一个时间片,若进程未全部执行结束,将其插入队尾,等待下次分配. 在进行插入队尾前判断 ...
最新文章
- 把Array说透(续一)
- 项目--教师日常办公平台中的活动图
- python for android 安装配置_mac appium for android 环境搭建 (appium python pycharm)
- JPM Coin三部曲 (上) :深入理解摩根幣的運作
- 5 thinkpad 黑将评测_ThinkPad L380视频评测:全能型商务助手
- 用注册机破解navicat12
- openpyxl使用教程
- Mac连接京瓷打印机Fs-1030MFP/DP
- {黑科技}哔哩哔哩视频三倍速播放
- oracle startup mount是什么意思,startup,startup mount,startup nomount之间的区别-Oracle
- 基于Android技术的物联网应用开发
- Stimulsoft Reports报告工具,Stimulsoft创建和构建报告
- AIGC席卷,抖快、阅文、知乎大战网文圈
- 关于517coding的10月月赛
- python保存不了是怎么回事_每天的微博热点保存不了怎么办?python帮你实现微博热点下载...
- 中兴盒子B860AV1.1-T2版刷公版固件教程
- 华为防火墙故障处理工具之查看路由表
- sct分散加载文件格式与应用
- 深入理解 Flink 容错机制
- MYSQL 存储过程的简单使用
热门文章
- python自动登录校园网_python实现校园网一键自动连接
- Win 10系统安装3ds max 2014
- 操作系统:临界区、临界资源的概念及相关习题
- 基于 Matlab的录屏软件
- 为什么子进程要继承处理器亲缘性?
- 计算机音乐创作是什么,计算机音乐创作,creation of computer music,音标,读音,翻译,英文例句,英语词典...
- 关于如何设置收藏本站和设为首页
- 【error】_smartbi数据集超出最大行数: DataRows > 1000
- 5分钟白嫖我常用的免费效率软件/工具!效率300% up!
- 人脸表情系列:论文阅读——Facial Expression Recognition by De-expression Residue Learning