C++模拟多级反馈队列(MLFQ)
MLFQ规则:
1.多个优先级队列(本模拟实验设置为三个优先级队列)
2.处于最高优先级的队列里的进程永远比低优先级队列里的进程先执行
3.同队列可采用轮转和先来先服务算法(本模拟实验采用轮转)
4.新加入的进程在最高优先级队列
5.在CPU运行期时间片到则降低优先级
程序说明
使用struct模拟进程PCB,实操可运行,可根据需要自选函数模块以实现功能
实验功能:
/*
* 输入:进程ID,所需要的CPU资源,所需要的IO资源,先执行CPU or IO
* 第一次执行是指定先执行cpu或者io,此后该程序cpu,io交替执行
* 若在进程执行 cpu时候 时间片到,降级,最低级不再降
* 若在进程执行 io时候 时间片到,升级,最高级不再升
* 若程序执行完CPU或者IO后 时间片未到,程序执行剩余的IO或者CPU
* 最终在第一级队列结束的是IO密集型,不管输入CPU,IO是多少,IO多则升级,CPU多则降级
* 限时输入,若不输入程序过几秒自动运行(秒数可以自己设置)
* 随时中断,进程运行过程中可以添加新进程
* 有抢占,添加的新进程进入第一队列,并且立马执行
* 第一级队列不会发生抢占,但仍然可以添加新进程,进程排到第一级队列尾
* 被抢占的进程返回进程所在队列的队尾等待执行
* 被抢占的进程在轮到该进程后继续上次剩余的时间片
* 可选择是否使用RunIO_CPU() 函数,该函数是在运行IO时记录时间片,并寻找最高优先级的进程运行CPU,达到模拟有进程在运行IO的时候,同时有别的进程在运行CPU
*/
头文件定义:
#include<ctime>
#include<vector>
#include<conio.h>
using namespace std;
#define PROCESS_MAX 10//进程池数
#define RUNTIME 0.5 //正在运行的间隔秒数
#define WAITINPUT 3 //第一队列等待输入的秒数
#define SLEEP 3 //第一队列模拟程序运行用的秒数
#define QUEUE1_SLICE 10//各个优先级队列的时间片
#define QUEUE2_SLICE 20
#define QUEUE3_SLICE 40
struct PCB {
string ID;//进程ID
bool status;//进程状态
int source_cpu;//需要的cpu资源
int source_io;//需要的io资源
int slice = 0;//记录被中断时已经获得的时间片
int choice = 0;//默认0是优先运行CPU,交替运行cpu,io
};
void CreateProcess();//创建进程
void AskIfNewPcb();//询问函数,可以在运行期间调用创建进程函数
bool Running(PCB& run_pcb, int queuenum, int mod, int timeslice);//模拟运行函数
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum);//模拟该进程正在使用CPU资源,该函数有重载
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum);//模拟该进程正在使用IO资源,该函数有重载
void RunContinue(PCB& run_pcb, int QUEUE_SLICE, int queuenum);//继续中断运行函数
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice);//重载,用于中断之后的运行
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice);//重载,用于中断之后的运行
void RunQueue1(PCB& run_pcb);//运行第一队列
void RunQueue2(PCB& run_pcb);
void RunQueue3(PCB& run_pcb);
void RunProcess();//运行进程
void Cpu_Io();//判断该进程是属于CPU密集型还是IO密集型
bool JudgeOver(const PCB& run_pcb, int queuenum);//判断进程是否运行完毕
void ShowRun(const PCB& run_pcb);//显示运行信息
void UpLevel(const PCB& run_pcb, int queuenum);//升级
void DownLevel(PCB& run_pcb, int queuenum);//降级
void PopQueue(int queuenum);//弹出队列
void EmptyRun(PCB& run_pcb);//检测空跑
void RunIO_CPU(PCB& run_pcb);//可选函数,模拟运行IO的同时另一个进程在运行CPU
.cpp文件定义:
#include"B.h"
int process_num = 0;//记录线程数量
PCB pcb[PROCESS_MAX];//进程池
queue<PCB> queue1;//第一级优先级队列
queue<PCB> queue2;
queue<PCB> queue3;
vector<PCB> process_cpu;//用于存放cpu密集型的进程的矢量容器
vector<PCB> process_io;
enum { CPU = 1, IO = 2 };
int io_slice = 0;//可选函数使用的参数
.cpp文件函数定义:
bool JudgeOver(const PCB& run_pcb, int queuenum)
bool JudgeOver(const PCB& run_pcb, int queuenum)
{
if (run_pcb.source_cpu == 0 && run_pcb.source_io == 0) {
cout << "进程运行完毕,弹出队列,结束进程." << endl;
if (queuenum == 1) {
///如果是在第一队列结束,就是IO密集型
process_io.push_back(run_pcb);
}
else {
process_cpu.push_back(run_pcb);
}
PopQueue(queuenum);
return true;
}
else {
return false;
}
}
void ShowRun(const PCB& run_pcb)
void ShowRun(const PCB& run_pcb)
{
cout << "---------------------------------------------" << endl;
cout << "※进程 " << run_pcb.ID << " 需要IO资源:" << run_pcb.source_io << endl;
cout << "※进程 " << run_pcb.ID << " 需要CPU资源:" << run_pcb.source_cpu << endl;
cout << "---------------------------------------------" << endl;
return;
}
void Cpu_Io()
void Cpu_Io()
{
cout << endl << "---------------------------------------------" << endl;
cout << "CPU密集型:" << endl;
for (vector<PCB>::iterator p = process_cpu.begin(); p != process_cpu.end(); p++) {
cout << "ID:" << (*p).ID << endl;
}
cout << "---------------------------------------------" << endl;
cout << "IO密集型:" << endl;
for (vector<PCB>::iterator p = process_io.begin(); p != process_io.end(); p++) {
cout << "ID:" << (*p).ID << endl;
}
cout << "---------------------------------------------" << endl;
}
void UpLevel(const PCB& run_pcb, int queuenum)
void UpLevel(const PCB& run_pcb, int queuenum)
{
/*cout << "※进程 " << run_pcb.ID << " 还需要 CPU 资源:" << run_pcb.source_cpu << endl;
cout << "※进程 " << run_pcb.ID << " 还需要 IO 资源:" << run_pcb.source_io << endl;*/
if (queuenum == 1) {
cout << "进程已在第一队列,保持优先级" << endl;
queue1.push(run_pcb);
PopQueue(queuenum);
return;
}
cout << "※进程 " << run_pcb.ID << " 已被升级" << endl;
cout << "※进程 " << run_pcb.ID << " 已被加入第 " << queuenum - 1 << " 队列" << endl;
if (queuenum == 2) {
queue1.push(run_pcb);
PopQueue(queuenum);
return;
}
else {
queue2.push(run_pcb);
PopQueue(queuenum);
return;
}
}
void DownLevel(PCB& run_pcb,int queuenum)
void DownLevel(PCB& run_pcb,int queuenum)
{
if (queuenum == 3) {
cout << "进程已在第三队列,保持优先级" << endl;
queue3.push(run_pcb);
PopQueue(queuenum);
return;
}
cout << "※进程 " << run_pcb.ID << " 已被降级" << endl;
cout << "※进程 " << run_pcb.ID << " 已被加入第 " << queuenum + 1 << " 队列" << endl;
if (queuenum == 1) {
queue2.push(run_pcb);
PopQueue(queuenum);
return;
}
else {
queue3.push(run_pcb);
PopQueue(queuenum);
return;
}
}
void PopQueue(int queuenum)
void PopQueue(int queuenum)
{
if (queuenum == 1) {
queue1.pop();
return;
}
else if (queuenum == 2) {
queue2.pop();
return;
}
else {
queue3.pop();
return;
}
}
void CreateProcess()
void CreateProcess()
{
cout << endl << "---------------------------------------------" << endl;
cout << "正在创建进程..." << endl;
if (process_num == 10) {
cout << "进程池已满,无法创建新进程." << endl;
return;
}
cout << "输入进程的ID,所需要的 CPU IO 资源数量:";
string id;
int cpu, io;
cin >> id >> cpu >> io;
pcb[process_num] = { id,false,cpu ,io };
cout << "该进程是优先运行CPU还是优先运行IO?0.CPU 1.IO:";
int choice;
cin >> choice;
pcb[process_num].choice = choice;
cout << "创建进程成功,正在入队列1..." << endl;
queue1.push(pcb[process_num]);
cout << "进程 " << id << " 成功入列1." << endl;
cout << endl << "---------------------------------------------" << endl;
process_num++;
}
void AskIfNewPcb()
void AskIfNewPcb()
{
clock_t start = clock();
//cout << "正在监听输入 (*_*) ... :";
char i;
while (true) {
if (_kbhit()) {
i = getchar();
if (i == '1') {
cout << endl;
CreateProcess();
return;
}
if (i == '0') {
cout << endl;
return;
}
}
clock_t end = clock();
if (long(end - start) / CLOCKS_PER_SEC >= WAITINPUT) {
return;
}
}
}
void RunContinue(PCB& run_pcb, int QUEUE_SLICE, int queuenum)
void RunContinue(PCB& run_pcb, int QUEUE_SLICE, int queuenum)//继续中断运行
{
int afterslice = QUEUE_SLICE - run_pcb.slice;
if (run_pcb.choice == 0) {
cout << "※进程 " << run_pcb.ID << " 恢复上次运行,并继续上次的 CPU 剩余的时间片:" << afterslice << endl;
RunCPU(run_pcb, QUEUE_SLICE, queuenum,afterslice);
return;
}
else {
cout << "※进程 " << run_pcb.ID << " 恢复上次运行,并继续上次的 IO 剩余的时间片:" << afterslice << endl;
RunIO(run_pcb, QUEUE_SLICE, queuenum, afterslice);
return;
}
}
bool Running(PCB& run_pcb, int queuenum, int mod, int timeslice)
bool Running(PCB& run_pcb, int queuenum, int mod, int timeslice)//模拟while循环的进程运行函数,里面有中断
{
if (queuenum == 1) {
//如果在队列1运行时有新进程加入,不会产生中断
cout << "※进程 " << run_pcb.ID << " 正在运行(敲击键盘可中断)..." << endl;
_sleep(RUNTIME * 1000);//模拟运行
AskIfNewPcb();
return true;
}
run_pcb.slice = 0;
while (run_pcb.slice < timeslice) {
cout << "※进程 " << run_pcb.ID << " 正在运行(敲击键盘可中断)..." << run_pcb.slice << endl;
_sleep(RUNTIME * 1000);//模拟运行
run_pcb.slice++;
if (_kbhit()) {
cout << "检测到输入,该进程被中断,返回队尾" << endl;
if (mod == CPU) {
run_pcb.source_cpu = run_pcb.source_cpu - run_pcb.slice;
}
else {
run_pcb.source_io = run_pcb.source_io - run_pcb.slice;
}
if (queuenum == 2) {
queue2.pop();
queue2.push(run_pcb);
}
else {
queue3.pop();
queue3.push(run_pcb);
}
AskIfNewPcb();
return false;
}
}
//运行完while说明没有被中断,置零slice给下次使用
run_pcb.slice = 0;
return true;
}
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum)
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum)
{
RunIO_CPU(run_pcb);
if (JudgeOver(run_pcb, queuenum) == true) {
return;
}
run_pcb.choice = 1;//更改状态,下次运行IO
if (run_pcb.source_cpu <= QUEUE_SLICE) {
//cpu资源在一个时间片里能运行完毕
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, CPU, run_pcb.source_cpu) == false) {
return;
}
int timeslice = QUEUE_SLICE - run_pcb.source_cpu;
run_pcb.source_cpu = 0;//cpu在一个时间片里运行完毕
cout << "运行CPU完毕,开始运行IO..." << endl;
RunIO(run_pcb, QUEUE_SLICE, queuenum, timeslice);
return;
}
else {
//cpu资源在一个时间片里运行不完
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, CPU, QUEUE_SLICE) == false) {
return;
}
run_pcb.source_cpu = run_pcb.source_cpu - QUEUE_SLICE;
cout << "时间片用完,CPU未全部运行完毕,降级." << endl;
DownLevel(run_pcb, queuenum);
return;
}
}
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum)
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum)
{
if (JudgeOver(run_pcb, queuenum) == true) {
return;
}
run_pcb.choice = 0;//更改状态,下次运行CPU
if (run_pcb.source_io <= QUEUE_SLICE) {
io_slice += run_pcb.source_io;
//io资源在一个时间片里能运行完毕
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, IO, run_pcb.source_io) == false) {
return;
}
int timeslice = QUEUE_SLICE - run_pcb.source_io;
run_pcb.source_io = 0;//IO在一个时间片里运行完毕
cout << "运行IO完毕,开始运行CPU..." << endl;
RunCPU(run_pcb, QUEUE_SLICE, queuenum, timeslice);
return;
}
else {
//io资源在一个时间片里运行不完
io_slice += QUEUE_SLICE;
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, IO, QUEUE_SLICE) == false) {
return;
}
run_pcb.source_io = run_pcb.source_io - QUEUE_SLICE;
cout << "时间片用完,IO未全部运行完毕,升级." << endl;
UpLevel(run_pcb, queuenum);
return;
}
}
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice)
void RunCPU(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice)
{
RunIO_CPU(run_pcb);
if (JudgeOver(run_pcb, queuenum) == true) {
return;
}
if (run_pcb.source_cpu <= afterslice) {
//cpu在剩余的时间片里可以运行完毕
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, CPU, run_pcb.source_cpu) == false) {
return;
}
int afterslice = QUEUE_SLICE - run_pcb.source_cpu;
run_pcb.source_cpu = 0;//cpu在一个时间片里运行完毕
cout << "运行CPU完毕,开始运行IO..." << endl;
RunIO(run_pcb, QUEUE_SLICE, queuenum, afterslice);
return;
}
else {
//cpu在剩余的时间里不能运行完毕
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, CPU, afterslice) == false) {
return;
}
run_pcb.source_cpu = run_pcb.source_cpu - afterslice;
cout << "时间片用完,CPU未全部运行完毕,降级." << endl;
run_pcb.status = false;
DownLevel(run_pcb, queuenum);
return;
}
}
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice)
void RunIO(PCB& run_pcb, int QUEUE_SLICE, int queuenum, int afterslice)
{
if (JudgeOver(run_pcb, queuenum) == true) {
return;
}
if (run_pcb.source_io <= afterslice) {
//cpu在剩余的时间片里可以运行完毕
io_slice += run_pcb.source_io;
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, IO, run_pcb.source_io) == false) {
return;
}
int afterslice = QUEUE_SLICE - run_pcb.source_io;
run_pcb.source_io = 0;//cpu在一个时间片里运行完毕
cout << "运行IO完毕,开始运行CPU..." << endl;
RunCPU(run_pcb, QUEUE_SLICE, queuenum, afterslice);
return;
}
else {
//cpu在剩余的时间里不能运行完毕
io_slice += QUEUE_SLICE;
ShowRun(run_pcb);
if (Running(run_pcb, queuenum, IO, afterslice) == false) {
return;
}
run_pcb.source_io = run_pcb.source_io - afterslice;
cout << "时间片用完,IO未全部运行完毕,升级." << endl;
run_pcb.status = false;
UpLevel(run_pcb, queuenum);
return;
}
}
void RunQueue1(PCB& run_pcb)
void RunQueue1(PCB& run_pcb)
{
int queuenum = 1;
int slice = QUEUE1_SLICE;
cout << "队列1 时间片:【" << slice << "】 队列1 已出列1个进程:<" << run_pcb.ID << ">" << endl;
run_pcb.status = true;
if (run_pcb.slice != 0) {
//恢复上次运行
RunContinue(run_pcb,QUEUE1_SLICE, queuenum);
return;
}
if (run_pcb.choice == 0 && run_pcb.source_cpu != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行CPU..." << endl;
RunCPU(run_pcb, QUEUE1_SLICE, queuenum);
return;
}
if(run_pcb.choice == 1 && run_pcb.source_io != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行IO..." << endl;
RunIO(run_pcb, QUEUE1_SLICE, queuenum);
return;
}
}
void RunQueue2(PCB& run_pcb)
void RunQueue2(PCB& run_pcb)
{
int queuenum = 2;
int slice = QUEUE2_SLICE;
cout << "队列2 时间片:【" << slice << "】 队列2 已出列1个进程:<" << run_pcb.ID << ">" << endl;
run_pcb.status = true;
if (run_pcb.slice != 0) {
RunContinue(run_pcb, QUEUE2_SLICE, queuenum);
return;
}
if (run_pcb.choice == 0 && run_pcb.source_cpu != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行CPU..." << endl;
run_pcb.choice = 1;
RunCPU(run_pcb, QUEUE2_SLICE, queuenum);
return;
}
if(run_pcb.choice == 1 && run_pcb.source_io != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行IO..." << endl;
run_pcb.choice = 0;
RunIO(run_pcb, QUEUE2_SLICE, queuenum);
return;
}
}
void RunQueue3(PCB& run_pcb)
void RunQueue3(PCB& run_pcb)
{
int queuenum = 3;
int slice = QUEUE3_SLICE;
cout << "队列3 时间片:【" << slice << "】 队列3 已出列1个进程:<" << run_pcb.ID << ">" << endl;
run_pcb.status = true;
if (run_pcb.slice != 0) {
RunContinue(run_pcb, QUEUE3_SLICE, queuenum);
return;
}
if (run_pcb.choice == 0 && run_pcb.source_cpu != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行CPU..." << endl;
run_pcb.choice = 1;
RunCPU(run_pcb, QUEUE3_SLICE, queuenum);
return;
}
if(run_pcb.choice == 1 && run_pcb.source_io != 0) {
cout << "※进程 " << run_pcb.ID << " 优先运行IO..." << endl;
run_pcb.choice = 0;
RunIO(run_pcb, QUEUE3_SLICE, queuenum);
return;
}
}
void RunProcess()
void RunProcess()
{
if (process_num == 0) {
cout << endl << "---------------------------------------------" << endl;
cout << "进程池为空,无法运行." << endl;
cout << endl << "---------------------------------------------" << endl;
return;
}
while (true) {
if (queue1.size() > 0) {
cout << endl << "=============================================" << endl;
PCB run_pcb = queue1.front();
EmptyRun(run_pcb);
RunQueue1(run_pcb);
cout << "=============================================" << endl;
}
else if (queue1.size() == 0 && queue2.size() > 0) {
cout << endl << "=============================================" << endl;
PCB run_pcb = queue2.front();
EmptyRun(run_pcb);
RunQueue2(run_pcb);
cout << "=============================================" << endl;
}
else if (queue2.size() == 0 && queue3.size() > 0) {
cout << endl << "=============================================" << endl;
PCB run_pcb = queue3.front();
EmptyRun(run_pcb);
RunQueue3(run_pcb);
cout << "=============================================" << endl;
}
else {
cout << "所有队列运行完毕!" << endl;
cout << "---------------------------------------------" << endl;
return;
}
}
}
void EmptyRun(PCB& run_pcb)
void EmptyRun(PCB& run_pcb) {
if (run_pcb.choice == 1 && run_pcb.source_io == 0) {
run_pcb.choice = 0;
return;
}
if (run_pcb.choice == 0 && run_pcb.source_cpu == 0) {
run_pcb.choice = 1;
return;
}
}
void RunIO_CPU(PCB& run_pcb)
void RunIO_CPU(PCB& run_pcb)
{
if (io_slice == 0) {
cout << "io_slice=0" << endl;
return;
}
else {
if (run_pcb.source_cpu != 0) {
if (run_pcb.source_cpu <= io_slice) {
cout << "进程" << run_pcb.ID << "该进程在上次运行IO时,已经运行完CPU资源" << endl;
run_pcb.source_cpu = 0;
return;
}
else {
cout << "进程" << run_pcb.ID << "该进程在上次运行IO时,已经运行一部分CPU资源" << endl;
run_pcb.source_cpu = run_pcb.source_cpu - io_slice;
return;
}
io_slice = 0;
}
}
}
顶层实现.cpp
#include"B.h"
int main()
{
enum{
Create=1,
Run=2,
Exit=0
};
cout << "输入:1.创建进程 2.运行进程池 0.退出 :";
int i;
cin >> i;
while (i != Exit) {
switch (i)
{
case Create: {
CreateProcess();
break;
}
case Run: {
RunProcess();
Cpu_Io();
break;
}
default:
break;
}
cout << "输入:1.创建进程 2.运行进程池 0.退出 :";
cin >> i;
}
return 0;
}