mlfq调度器通过三级队列实现动态优先级调整:新进程初始level=0;时间片耗尽且未完成则降级至下一级(最高level=2);等待≥20ms或io完成则提权至level=0;每时刻按队列优先级调度,输出运行与完成日志。

你需要在C++中模拟一个多级反馈队列(MLFQ)调度器,能真实反映进程随等待时间增长而提升优先级、随CPU爆发性运行而降级的动态行为,并输出每时刻的调度决策与队列状态。
定义进程结构体与多级队列容器
创建Process类,包含pid、到达时间arrive、所需总CPU时间burst、已执行时间executed、当前所在队列等级level(0为最高优先级)、上一次被抢占的时间last_preempt。注意:level必须初始化为0,否则新进程不会进入最高级队列。
用vector
实现动态优先级升降逻辑
方法一:时间片耗尽降级
当进程在第k级队列中用完其时间片(如第0级为4ms、第1级为8ms、第2级为16ms),且burst > executed,则将其level设为min(level + 1, 2),executed不变,插入queues[level]队尾。
方法二:等待超时提权
在每个时间单位推进前,遍历所有低优先级队列(level ≥ 1)的队首进程:若当前仿真时间 - 进程arrive ≥ 20ms(即等待超20ms),则将其level重置为0,executed不变,push入queues[0]队尾。这一步必须在调度前执行,否则提权失效。
方法三:IO阻塞后重置优先级
若进程主动发起IO(由输入数据标记),则直接将其level = 0,executed保持不变,插入queues[0]。IO完成时间由输入指定,需维护一个IO就绪事件队列,在对应时刻触发此操作。
主仿真循环:按时间单位推进
第一步:检查是否有新进程在当前时间t到达 → 若有,将该Process对象插入queues[0]队尾。
第二步:执行等待提权逻辑 → 遍历queues[1]和queues[2]中所有进程,对满足等待超时条件者执行level=0并移入queues[0]。
第三步:尝试调度 → 从queues[0]开始向下扫描,找到第一个非空队列,取其队首进程。若该进程所在队列为level=k,则分配对应时间片time_slice[k](如{4,8,16})。
第四步:执行该进程最多time_slice[k]单位 → 实际执行时间actual = min(time_slice[k], burst - executed);更新executed += actual;若executed == burst,则记录完成时间并移出队列;否则,按方法一判断是否降级,再决定去向。
第五步:处理IO事件 → 查找IO完成时间等于当前t的事件,对对应进程执行方法三提权操作。
注意:所有队列操作必须使用queue的front()/pop()/push(),不可随机访问或遍历内部元素;否则无法模拟真实FIFO调度语义。
输入解析与初始化
从标准输入读取n个进程,每行格式为:pid arrive burst io_time(io_time为-1表示无IO,否则表示该进程在执行完io_time单位后发起IO请求)。需要预处理:为每个进程生成IO就绪事件(时间 = arrive + io_time),存入priority_queue
【必须在读入后立即为每个进程设置level = 0】,否则它们将被错误地放入低优先级队列导致调度失序。
输出调度过程日志
每执行一个时间单位,输出格式为:[t] run pid:xx, remain:yy, level:z → 表示t时刻正在运行pid为xx的进程,剩余burst为yy,当前位于第z级队列。
进程完成时额外输出:[t] finish pid:xx, turnaround:TT, wait:WW → 其中TT = t - arrive,WW = TT - burst。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











