RR算法 调度
RR算法是使用非常广泛的一种调度算法。
首先将所有就绪的队列按FCFS策略排成一个就绪队列,然后系统设置一定的时间片,每次给队首作业分配时间片。如果此作业运行结束,即使时间片没用完,立刻从队列中去除此作业,并给下一个作业分配新的时间片;如果作业时间片用完没有运行结束,则将此作业重新加入就绪队列尾部等待调度。
- //main.cpp
- #include "RR.h"
- int main()
- {
- std::vector<PCB> PCBList;
- int timeslice;
- //输入时间片大小,作业信息
- InputPCB(PCBList, timeslice);
- //RR算法
- RR(PCBList, timeslice);
- //显示结果
- show(PCBList);
- return 0;
- }
- //RR.h
- #ifndef RR_H_
- #define RR_H_
- #include <iostream>
- #include <algorithm>
- #include <iomanip>
- #include <vector>
- #include <queue>
- //作业结构体
- typedef struct PCB
- {
- int ID; //标识符
- int ComeTime; //到达时间
- int ServerTime; //服务时间
- int FinishTime; //完成时间
- int TurnoverTime; //周转时间
- double WeightedTurnoverTime; //带权周转时间
- }PCB;
- /*
- 函数功能:输入作业信息
- 参数说明:
- PCBList std::vector<PCB>& PCB链
- timeslice int 时间片
- */
- void InputPCB(std::vector<PCB> &PCBList, int ×lice);
- /*
- 函数功能:RR算法
- 参数说明:
- PCBList std::vector<PCB>& PCB链
- */
- void RR(std::vector<PCB> &PCBList, int timeslice);
- /*
- 函数功能:显示结果
- 参数说明:
- PCBList std::vector<PCB>& PCB链
- */
- void show(std::vector<PCB> &PCBList);
- /*
- 函数功能:比较函数,用于sort(),按ComeTime升序排列
- 参数说明:
- p1 const PCB& PCB
- p2 const PCB& PCB
- */
- bool CmpByComeTime(const PCB &p1, const PCB &p2);
- #endif
- //RR.cpp
- #include "RR.h"
- //输入作业信息
- void InputPCB(std::vector<PCB> &PCBList,int ×lice)
- {
- std::cout << "输入时间片大小: ";
- std::cin >> timeslice;
- do {
- PCB temp;
- std::cout << "输入标识符: ";
- std::cin >> temp.ID;
- std::cout << "输入到达时间: ";
- std::cin >> temp.ComeTime;
- std::cout << "输入服务时间: ";
- std::cin >> temp.ServerTime;
- temp.FinishTime = 0; //暂时存放运行了多少时间,来判断此作业是否运行结束
- PCBList.push_back(temp);
- std::cout << "继续输入?Y/N: ";
- char ans;
- std::cin >> ans;
- if ('Y' == ans || 'y' == ans)
- continue;
- else
- break;
- } while (true);
- }
- //RR算法
- void RR(std::vector<PCB> &PCBList, int timeslice)
- {
- std::sort(PCBList.begin(), PCBList.end(), CmpByComeTime); //按到达时间排序
- std::vector<PCB> result; //保存结果
- std::queue<PCB> Ready; //就绪队列
- int BeginTime = (*PCBList.begin()).ComeTime; //第一个作业开始时间
- Ready.push(*PCBList.begin());
- PCBList.erase(PCBList.begin());
- while (!PCBList.empty() || !Ready.empty())
- {
- if (!PCBList.empty() && BeginTime >= (*PCBList.begin()).ComeTime) //有新作业到达,加入就绪队列
- {
- Ready.push(*PCBList.begin());
- PCBList.erase(PCBList.begin());
- }
- if (Ready.front().FinishTime + timeslice < Ready.front().ServerTime) //时间片用完没运行完,加入队尾
- {
- Ready.front().FinishTime += timeslice;
- Ready.push(Ready.front());
- Ready.pop();
- BeginTime += timeslice;
- }
- else //此作业运行完
- {
- BeginTime += Ready.front().ServerTime - Ready.front().FinishTime;
- Ready.front().FinishTime = BeginTime;
- Ready.front().TurnoverTime = Ready.front().FinishTime - Ready.front().ComeTime;
- Ready.front().WeightedTurnoverTime = (double)Ready.front().TurnoverTime / Ready.front().ServerTime;
- //从就绪队列中移除作业
- result.push_back(Ready.front());
- Ready.pop();
- }
- }
- //按ComeTime升序排序,便于显示结果
- PCBList = result;
- std::sort(PCBList.begin(), PCBList.end(), CmpByComeTime);
- }
- //显示结果
- void show(std::vector<PCB> &PCBList)
- {
- int SumTurnoverTime = 0;
- double SumWeightedTurnoverTime = 0;
- std::cout.setf(std::ios::left);
- std::cout << std::setw(20) << "标识符";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- std::cout << std::setw(5) << (*it).ID;
- std::cout << std::endl;
- std::cout << std::setw(20) << "到达时间";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- std::cout << std::setw(5) << (*it).ComeTime;
- std::cout << std::endl;
- std::cout << std::setw(20) << "服务时间";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- std::cout << std::setw(5) << (*it).ServerTime;
- std::cout << std::endl;
- std::cout << std::setw(20) << "完成时间";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- std::cout << std::setw(5) << (*it).FinishTime;
- std::cout << std::endl;
- std::cout << std::setw(20) << "周转时间";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- {
- std::cout << std::setw(5) << (*it).TurnoverTime;
- SumTurnoverTime += (*it).TurnoverTime;;
- }
- std::cout << std::endl;
- std::cout << std::setw(20) << "带权周转时间";
- for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it)
- {
- std::cout << std::setw(5) << (*it).WeightedTurnoverTime;
- SumWeightedTurnoverTime += (*it).WeightedTurnoverTime;;
- }
- std::cout << std::endl;
- std::cout << "平均周转时间: " << (double)SumTurnoverTime / PCBList.size() << std::endl;
- std::cout << "平均带权周转时间: " << SumWeightedTurnoverTime / PCBList.size() << std::endl;
- }
- //比较函数,按ComeTime升序排列
- bool CmpByComeTime(const PCB &p1, const PCB &p2)
- {
- return p1.ComeTime < p2.ComeTime;
- }
RR算法 调度的更多相关文章
- 操作系统概念学习笔记 10 CPU调度
操作系统概念学习笔记 10 CPU调度 多道程序操作系统的基础.通过在进程之间切换CPU.操作系统能够提高计算机的吞吐率. 对于单处理器系统.每次仅仅同意一个进程执行:不论什么其它进程必须等待,直到C ...
- [Linux]Linux系统调用列表
本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...
- LVS负载均衡集群服务搭建详解(二)
lvs-nat模型构建 1.lvs-nat模型示意图 本次构建的lvs-nat模型的示意图如下,其中所有的服务器和测试客户端均使用VMware虚拟机模拟,所使用的CentOS 7 VS内核都支持ipv ...
- 常用的Linux系统调用命令
常用的Linux系统调用命令 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 ...
- Linux系统调用(转载)
目录: 1. Linux系统调用原理 2. 系统调用的实现 3. Linux系统调用分类及列表 4.系统调用.用户编程接口(API).系统命令和内核函数的关系 5. Linux系统调用实例 6. Li ...
- Linux系统调用列表
转自Linux系统调用列表 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtabl ...
- Linux常用系统调用
转载 http://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html#icomments 按照惯例,这个列表 ...
- 【转】Linux系统调用列表
一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtablesize 进程所能打开的最 ...
- Linux系统常见调用及其分类
Linux系统调用主要可以分为以下几类: 进程控制 fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 get ...
随机推荐
- php创建udp Server
<?php//服务器信息$server = 'udp://127.0.0.1:7002';//----UDP Server$msgEof = "\n";$socket = s ...
- MySql开启远程用户登录GRANTALLPRIVILEGESON*.*TO'root'@'%'I MySql开启远程用户登录GRANTALLPRIVILEGESON*.*TO'root'@'%'I
MySql开启远程用户登录 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'huawei' WITH GRANT OPTION; FL ...
- 使用time模块,转化时间格式
import time ''' 时间戳:表示1970年开始计算的偏移量.我们运用type(时间戳)是float类型 结构化时间:9个元素组成的数组 格式化时间字符串 ''' '''获取当前时间戳''' ...
- USBWriter之后恢复磁盘大小
USBWriter之后恢复磁盘大小的方法: 1,cmd 2,diskpart 3,list disk 4,select disk *(*你的U盘代号) (e.g:U盘为磁盘 2 ,则代号为2 ,使用命 ...
- python 数字
python数字: 本文主要讲解常用的数字类型转换, 数字函数和随机数字函数. # coding:utf-8 # python数字类型转换 def data_conversion(): "& ...
- 使用 Docker 搭建 Tomcat 运行环境
转自: http://m.oschina.net/blog/616526, 版权归原作者所有. 1 Docker与虚拟机 2 搭建过程 2.1 准备宿主系统 准备一个 CentOS 7操作系统 ...
- android:View的setTag和getTag
Adapter 有个getView方法,可以使用setTag把查找的view缓存起来方便多次重用 public View getView(int position, View convertView, ...
- springmvc 动态加载配置文件
<import resource="classpath:config/spring-profile-properties.xml" /> <context:pro ...
- 开源框架完美组合之Spring.NET + NHibernate + ASP.NET MVC + jQuery + easyUI 中英文双语言小型企业网站Demo(转)
热衷于开源框架探索的我发现ASP.NET MVC与jQuery easyUI的组合很给力.由于原先一直受Ext JS框架的licence所苦恼,于是痛下决心寻找一个完全免费的js框架——easyUI. ...
- linux下open和fopen的区别
二者返回值不同. fopen可以指定宽字符和ASCI.