多级反馈队列调度算法(MFQ)
多级反馈队列调度算法是目前公认的较好的一种进程调度算法,它能较好的满足各类进程的需要。
MFQ算法首先设置多个就绪队列。队列的优先级递减,且各队列时间片大小也不同。例如我实现的算法里,设置了3个队列,第一队列优先级>第二队列>第三队列,且后一个队列的时间片大小是前一个的2倍。
每个队列都采用FCFS策略排列。首先调度高优先级队列内的进程,如果此进程在时间片内不能运行完,则将它加入下一个队列。这样到了最后一个队列,就成了RR算法。
如果有高优先级的进程到达,则放弃正在调度的进程,转向调度最高优先级的进程。这里我的实现不是很完美,我的算法里当高优先级进程到达时,如果有进程正在运行,则需要等到这个进程时间片结束才能转到高优先级进程。需要进一步修改,今晚困了,改不动了
//main.cpp
#include "MFQ.h"int main()
{std::vector<PCB> PCBList;int timeslice;//输入时间片大小,作业信息InputPCB(PCBList, timeslice);//MFQ算法MFQ(PCBList, timeslice);//显示结果show(PCBList);return 0;
}//MFQ.h
#ifndef MFQ_H_
#define MFQ_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);/*
函数功能:MFQ算法
参数说明:
PCBList std::vector<PCB>& PCB链
timeslice int 第一队列时间片
*/
void MFQ(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//MFQ.cpp
#include "MFQ.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;elsebreak;} while (true);
}//MFQ算法
void MFQ(std::vector<PCB> &PCBList, int timeslice)
{std::sort(PCBList.begin(), PCBList.end(), CmpByComeTime); //按到达时间排序std::vector<PCB> result; //保存结果int BeginTime = (*PCBList.begin()).ComeTime; //第一个作业开始时间const int QueueNum = 3;std::queue<PCB> Ready[QueueNum]; //设置3个就绪队列Ready[0].push(*PCBList.begin());PCBList.erase(PCBList.begin());while (!PCBList.empty()){//这段是为了防止前面的进程运行完了,后面的进程还没到,造成死循环bool flag = false;for (int i = 0; i < QueueNum; ++i){if (!Ready[i].empty()){flag = true;break;}}if(!flag){Ready[0].push(*PCBList.begin());PCBList.erase(PCBList.begin());BeginTime = Ready[0].front().ComeTime;}for (int i = 0; i < QueueNum; ++i){ int times = timeslice * (i + 1); //下一个队列的时间片大小是上一个的2倍if (i != QueueNum - 1) //不是最后一个队列{while (!Ready[i].empty()) //队列不空{if (!PCBList.empty() && BeginTime >= (*PCBList.begin()).ComeTime) //有新作业到达,加入就绪队列,转到第一队列{Ready[0].push(*PCBList.begin());PCBList.erase(PCBList.begin());i = 0; continue;}if (Ready[i].front().FinishTime + times < Ready[i].front().ServerTime) //时间片用完没运行完,加入下一队列队尾{Ready[i].front().FinishTime += times;Ready[i + 1].push(Ready[i].front());Ready[i].pop();BeginTime += times;}else //此作业运行完{BeginTime += Ready[i].front().ServerTime - Ready[i].front().FinishTime;Ready[i].front().FinishTime = BeginTime;Ready[i].front().TurnoverTime = Ready[i].front().FinishTime - Ready[i].front().ComeTime;Ready[i].front().WeightedTurnoverTime = (double)Ready[i].front().TurnoverTime / Ready[i].front().ServerTime;//从就绪队列中移除作业result.push_back(Ready[i].front());Ready[i].pop();}}}else{while (!Ready[i].empty()){if (!PCBList.empty() && BeginTime >= (*PCBList.begin()).ComeTime) //有新作业到达,加入就绪队列,转到第一队列{Ready[0].push(*PCBList.begin());PCBList.erase(PCBList.begin());i = -1;break;}if (Ready[i].front().FinishTime + times < Ready[i].front().ServerTime) //时间片用完没运行完,加入队尾{Ready[i].front().FinishTime += times;Ready[i].push(Ready[i].front());Ready[i].pop();BeginTime += times;}else //此作业运行完{BeginTime += Ready[i].front().ServerTime - Ready[i].front().FinishTime;Ready[i].front().FinishTime = BeginTime;Ready[i].front().TurnoverTime = Ready[i].front().FinishTime - Ready[i].front().ComeTime;Ready[i].front().WeightedTurnoverTime = (double)Ready[i].front().TurnoverTime / Ready[i].front().ServerTime;//从就绪队列中移除作业result.push_back(Ready[i].front());Ready[i].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.precision(2);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;
}
多级反馈队列调度算法(MFQ)相关推荐
- 多级反馈队列调度算法(附Python3实现代码)
一.多级反馈队列调度算法 多级反馈队列调度算法是进程调度的一种算法,该调度算法可以不用事先知道各种进程所需的执行时间,还可以较好的满足各种类型进程的需要,是目前共认的一种较好的进程调度算法. 那你可能 ...
- python实现进程调度算法_多级反馈队列调度算法(附Python3实现代码)
一.多级反馈队列调度算法 多级反馈队列调度算法是进程调度的一种算法,该调度算法可以不用事先知道各种进程所需的执行时间,还可以较好的满足各种类型进程的需要,是目前共认的一种较好的进程调度算法. 那你可能 ...
- 多级反馈队列调度算法原理
多级反馈队列调度算法是一种CPU处理机调度算法,UNIX操作系统采取的便是这种调度算法.
- 2.2.5 操作系统之调度算法(时间片轮转调度算法、优先级调度算法、多级反馈队列调度算法)
文章目录 0.思维导图 1.时间片轮转---RR 2.优先级调度算法 3.多级反馈队列调度算法 4.三种算法的对比总结 0.思维导图 1.时间片轮转-RR Round-Robin 时间片为2举例 以时 ...
- 【学习笔记】第二章——时间片轮转RR、优先级调度、多级反馈队列调度算法
文章目录 一. 时间片轮转 二. 优先级调度 三. 多级反馈队列调度算法 四. 总结 一. 时间片轮转 公平,轮流给进程提供时间片 只用于进程调度(只有进程才能被分配时间片) 抢占式,由时钟装置发出时 ...
- linux多级反馈队列的实现,多级反馈队列调度算法的实现
<多级反馈队列调度算法的实现>由会员分享,可在线阅读,更多相关<多级反馈队列调度算法的实现(16页珍藏版)>请在人人文库网上搜索. 1.学生实习报告课程名称_ 数据结构与数据处 ...
- 多级队列调度算法可视化界面_多级反馈队列调度算法
我是一名计算机专业的学生,很荣幸在这里结识各位编程高手.今天第一次写东西,希望大家多多支持,多多留言哦.以下是一个多级反馈队列调度算法,请各位帮忙看看对不对.如果谁能帮写一个更好的那就更感谢了.THA ...
- linux多级反馈队列的实现,多级反馈队列调度算法详解
通常在使用多级队列调度算法时,进程进入系统时被永久地分配到某个队列.例如,如果前台和后台进程分别具有单独队列,那么进程并不从一个队列移到另一个队列,这是因为进程不会改变前台或后台的性质.这种设置的优点 ...
- 多级反馈队列调度算法(c++)
如果对你有帮助,可以给卑微的博主留个赞.关注.收藏 (不是) (骗一下数据,说不定以后面试就过了,拜谢) 操作系统基本调度算法,多级反馈队列调度算法.在划分时间片的调度算法中,多级反馈队列算法兼顾 ...
最新文章
- html 乱码_html小坑:网页变成乱码
- 华为这台「技术暴力输出机」,亮出「云原生2.0」,研发效率飙升10倍!
- linux之用户态和内核态
- 8家大厂SSP offer的清华学长谈算法岗是否人间地狱(送七本学长手写iPad笔记)...
- python pyqt5 窗体自适应_Pyqt5自适应布局实例
- Matlab矩阵填充--Matlab interp2
- 虚拟机安装 xp步骤(参照百度文库)
- 安装keepalived高可用(双实例)
- php的运行方式及vc6和vc9,ts和nts区别
- 最流行的 .NET 反编译工具合集
- 中级软件设计师知识点总结
- DTCC 2018大会归来
- 华为2019年4月10日实习生笔试题
- 北京已开通5G基站6324个,年内目标建设超1万个5G基站
- NPOI操作Excel 让单元格的内容换行
- 【踩坑专栏】feign.codec.EncodeException: Error converting request body
- Win32:编译64位程序的注意点
- cmd脚本编程基础命令
- 初中数学分几个模块_谁整理的?超全初中数学四大板块思维导图汇总,初中生请签收!...
- 糖基化(glycosylation)