调度:多级反馈队列

article/2025/8/15 13:50:37

多级反馈队列(Multi-level Feedback Queue, MLFQ)是有Corbato在1962年提出的,用于兼容时分共享系统。现在其经过多年的优化,已经被应用于很多现代操作系统中。多级反馈队列是为了解决两方面问题。一:优化周转时间。在之前的进程调度中曾经提及过,这需要通过有线执行短工作来实现,但是问题是很少有进程可以在一开始就能正确预测它的工作要运行多久。第二个问题是降低响应时间,这可以通过时间片轮转等方法实现,但这些策略的周转时间却很差。所以出现了多级反馈队列,多级反馈队列是使用历史经验来预测未来的一种方式,操作系统中很多地方都采用这种技术,操作系统以外的计算机技术,例如硬件的分支预测、缓存算法等也都有这种思想的使用。

 

一、基本规则

正如它的名字所描述的那样,MLFQ中有多个队列,每个队列有不同的优先级。任何时刻,一个工作只能存在于一个队列中。MLFQ总是优先执行较高优先级的工作(即那些在较高级队列中的工作)。每个队列中可能会有多个工作,它们具有同样的优先级。在这种情况下,我们就对这些工作采用轮转调度。至此,我们得到了MLFQ的两条基本规则:

规则1:如果A的优先级大于B的优先级,运行A不运行B
规则2:如果A的优先级等于B的优先级,轮转运行A和B

同时也就发现了MLFQ的关键就在于多个队列的优先级如何设置,因为只有具有合理的优先级设置策略才能让操作系统真正的按照自己想要的顺序不停的切换执行进程。MLFQ不会为每个队列或每个工作设置一个固定的优先级,前面已经说了,MLFQ是使用历史经验来预测未来的一种方式,所以会在运行的过程中通过队列的反馈不断的调整对应的优先级。最简单的例子就是当你有两个程序同时在进行下载操作,那么当你使用鼠标点击其中一个程序,这个程序就需要立即响应你的鼠标操作,那么此时他的优先级就要被提高。

 

二、优先级的设置

考虑到实际使用中进程可能是有各种各样的情况,例如会有运行时间很短会频繁放弃CPU的多个小任务同时执行,也可能会有需要很多CPU时间,但响应时间却不重要的长时间计算密集型工作,等等等等,所以需要在前面的基础上调整算法:

规则3:工作进入系统时,放在最高优先级(最上层)队列
规则4a:工作用完整个时间片后,降低其优先级(移入低一级队列)
规则4b:如果工作在其时间片以内主动释放CPU,则优先级不变

场景1:单个长工作

假如系统中只有一个需要长时间运行的工作,那么按照当前的MLFQ调度执行的情况就如下图:

                                                            

首先,工作刚刚到来时直接进入最高优先级(Q2),因为此时没有人与他争夺CPU。在执行一个10ms的时间片后,调度程序将工作的优先级降低,放进Q1队列。在Q1执行一个时间片后,再次降低优先级进入系统的最低优先级(Q0),之后就一直留在那里。

场景2:长工作+短工作

A是一个长时间运行的CPU计算密集型工作,B是一个运行时间很短的交互型工作。假设A执行一段时间后B到达,那么此时运行情况如下:

                                                            

A(用黑色表示)在B到达之前的运行状态与场景1一致。B(用灰色表示)在时间为100ms时到达,此时会直接被加入最高优先级队列。由于它的运行时间很短(只有20ms),经过两个时间片,在被移入最低优先级队列之前,B执行完毕。然后A继续运行(在低优先级)。

可以看到MLFQ算法的目标是:在不知道工作是短工作还是长工作时,就假设其是短工作,并赋予最高优先级。如果确实是短工作,则很快会执行完毕,否则将被慢慢移入低优先级队列,而这时该工作也被认为是长工作了。通过这种方式,MLFQ近似于SJF。

场景3:结合I/O

根据上述规则4b,如果进程在时间片用完之前主动放弃CPU,则保持它的优先级不变。这条规则的意图很简单:假设交互型工作中有大量的I/O操作(比如等待用户的键盘或鼠标输入),它会在时间片用完之前放弃CPU。在这种情况下,我们不想处罚它,只是保持它的优先级不变。

下图展示了这个运行过程,交互型工作B(用灰色表示)每执行1ms便需要进行I/O操作,它与长时间运行的工作A(用黑色表示)竞争CPU。MLFQ算法保持B在最高优先级,因为B总是让出CPU。如果B是交互型工作,MLFQ就进一步实现了它的目标,让交互型工作快速运行。

                                                              

至此,可以看到一个基础版本的MLFQ。它与之前的调度算法比起来有了进步,长工作之间可以公平地分享CPU,又能给短工作或交互型工作很好的响应时间。但是,也能看到这种算法有一些非常严重的缺点。首先,会有饥饿问题。如果系统有“太多”交互型工作,就会不断占用CPU,导致长工作永远无法得到CPU,但实际上在这种情况下,长工作也应该在合适的时间被执行才能不会被认为是已经停止工作。其次,某些用户会用一些手段欺骗调度程序,让它给予进程远超公平的资源。例如,进程在时间片用完之前,调用一个I/O操作(比如访问一个无关的文件),从而主动释放CPU。如此便可以保持在高优先级,占用更多的CPU时间。假如可以将进程设置为每运行99%的时间片时间就主动放弃一次CPU,那么这个进程可以几乎独占CPU。最后,一个程序可能在不同时间表现不同。一个计算密集的进程可能在某段时间表现为一个交互型的进程,但在当前的算法下,它无法再回到最高优先级。

于是可以得到下一步的优化思路:对于一个进程不能将其认为是固定的长工作或是短工作,需要根据他实际的运行情况不停的调整他的状态。那么调整一个进程状态的时机选择条件该如何设置?考虑到操作系统需要基于时钟中断,那么可以人为的模拟出一种时钟中断,也就是定时调整所有进程的优先级。于是可以得到一条新的规则:

规则5:每经过一段时间,就将系统中所有工作重新加入最高优先级队列

当加入规则5之后,可以看到进程饿死的情况不会存在了,因为每隔一段时间每个进程都会变成最高优先级,也就是每隔一定时间就至少会被执行一次。同样,操作系统也就不会再被欺骗了,或者说被欺骗也无所谓,因为此时这种欺骗已经可以认为是合法的,规则5所做的其实只是以操作系统的角度允许了这种欺骗行为,当然欺骗还是与规则5不一样的,规则的主要目标是为了避免进程在长短两种工作状态切换时操作系统无法及时响应,而欺骗是单纯的长工作想要独占CPU。

在看一种新场景:长工作与两个交互型短工作竞争CPU时的行为。

下图左边没有优先级提升,长工作在两个短工作到达后被饿死。右边每50ms就有一次优先级提升,因此至少保证长工作每过50ms就被提升到最高优先级,从而定期获得执行。

                    

解决了前面的问题,但此时又得到了一个新的问题,调整优先级的时间间隔该如何确定?如果时间间隔过长,那么可能会执行完短工作才能将长工作的优先级调整,此时调整也没什么意义了;如果时间过短,长工作有因为不断被设为最高优先级会耽误短工作的尽快执行结束。经过前面的对操作系统不断完善,此时自然可以想到根据时间中断来设置时间间隔。但是如果简单的使用时钟中断来设置时间间隔那么不就又回到了时间片轮转算法了。所以就有了一个新的解决方案:为MLFQ的每层队列提供更完善的计时方式,也就是调度程序应该记录每个进程在某一层中消耗的总时间,而不是在调度时重新计时。只要进程用完了自己的配额,就将它降到低一级队列中去。不论它是一次用完的,还是拆成很多次用完。在这种方式下,可以重新规则4,得到:

规则4:一旦工作用完了其在某一层中的时间配额(无论中间主动放弃了多少次CPU),就降低其优先级(移入低一级队列)

此时来看一种情况:下图对比了在规则4a、4b的策略下(左),以及在新的规则4(右)的策略下,同样试图欺骗调度程序的进程的表现。没有规则4的保护时,进程可以在每个时间片结束前发起一次I/O操作,从而垄断CPU时间。有了这样的保护后,不论进程的I/O行为如何,都会慢慢地降低优先级,因而无法获得超过公平的CPU时间比例。

                                                              

 

最后其实MLFQ还有一些问题没有确切的答案。例如:配置多少个队列?每层队列时间片该为多大?具体该多久提升一次所有进程的优先级?这些其实没有一个令所有人百分百满意的答案,所以这些都是在对操作系统的不断优化中不断修改设置最终得到一个令大多数人至少是开发者满意的结果。例如,大多数的MLFQ变体都支持不同队列可变的时间片长度。高优先级队列通常只有较短的时间片(比如10ms或者更少),因而这一层的交互工作可以更快地切换。相反,低优先级队列中更多的是CPU密集型工作,配置更长的时间片会取得更好的效果。后来John Ousterhout教授提出了Ousterhout定律,也就是提供一组决定进程在生命周期中如何调整优先级,每层时间片多大,多久调整优先级的表。这个表可以由管理员更改,从而使得调度程序的行为方式不同。在不对表修改时,就采用默认的执行方式。另外现在这篇文章里所有对MLFQ的介绍都是基于操作系统超脱于MLFQ来讲的,也就是没有将操作系统看作是一个应用程序,但实际上有一些操作系统会将自己也看做是一个应用程序,但会将自己始终设置为最高优先级,并且不允许用户更改,这也是一种很有意思的实现方式。

 

最后,MLFQ的有趣原因在于它不需要对进程的运行信息有足够的了解,只要按照自己既有的规则执行即可实现对进程的合理调度。MLFQ基本可以满足各种工作的需求,对于短时间运行的交互性工作,可以获得类似于SJF/STCF的良好的全局性;对于长时间运行的计算密集型工作也可以让其在不长时间占用CPU的情况下不断地执行。所以现在很多系统都具有MLFQ,虽然具体时间可能天差地别,这些系统包括UNIX系统、Solaris以及Windows NT和其后的Windows系列操作系统。


http://chatgpt.dhexx.cn/article/T2LMYTna.shtml

相关文章

多级队列调度和多级反馈队列调度算法的实现

多级队列调度算法 操作系统实验导航 实验一:银行家算法 https://blog.csdn.net/weixin_46291251/article/details/115384510 实验二:多级队列调度和多级反馈队列调度算法 https://blog.csdn.net/weixin_46291251/article/details/115530582 实验三&…

多级反馈队列调度算法模拟实现

实验一 多级反馈队列调度算法 一. 主要实现方法和代码介绍 ​ 1.编写进程类,其只包含所需的运行时间和进程编号两个属性,还有一个运行方法,此方法就是将所需的运行时间属性减去.传入的运行时间. ​ 2.创建进程函数:创建maxp个进程,(应该不超过10,在此创建九个,即暂时不进行进…

计操实验 多级反馈队列C语言

计操实验 多级反馈队列C语言 需求: 1.队列4级,每一级的队列长度均为10;第一级的时间片为T,第二级的时间片为2T,第三级的时间片为4T,第四级的时间片为8T;(T的大小自己定) …

【操作系统】轮转和多级反馈队列

随着计算机的技术逐渐步入家用后,新的调度指标接踵而来,周转时间已经不能满足人们日常工作的需求,更多时候人们更希望计算机能有更好的交互性,使其能更快地去响应任务,由此针对优化响应时间的调度策略也遍地开花&#…

多级反馈队列调度算法(c++)

如果对你有帮助,可以给卑微的博主留个赞、关注、收藏 (不是) (骗一下数据,说不定以后面试就过了,拜谢) 操作系统基本调度算法,多级反馈队列调度算法。在划分时间片的调度算法中,多级反馈队列算法兼顾提高系统吞吐…

多级反馈队列调度算法

实验目的: 在Linux下编程实现多级反馈队列调度算法,采用三级调度策略,所有进程先按到达顺序进入一级队列,按照时间片为2轮转一次,一个时间片内未完成的进程被依次移入二队列尾部。当一级队列中没有进程时,开…

多级反馈队列调度

多级反馈队列 ​ 多级反馈队列(Multi-level Feedback Queue, MLFQ),与上个世纪70年代提出,主要应用于时分共享系统。主要解决两方面问题:一个是优化周转时间,一个是要给用户很好的交互体验。ML…

多级反馈队列算法

步骤: 0时刻,P1到达就绪队列(时间片为4的)P1先执行2ms,P2到达还未到时间片,P1继续执行2ms后,时间片到达了,P1滑到下一个就绪队列(时间片为6的)此时&#xff…

linux多级反馈队列的实现,多级反馈队列调度算法详解

通常在使用多级队列调度算法时,进程进入系统时被永久地分配到某个队列。例如,如果前台和后台进程分别具有单独队列,那么进程并不从一个队列移到另一个队列,这是因为进程不会改变前台或后台的性质。这种设置的优点是调度开销低&…

对数线性模型

http://blog.csdn.net/pipisorry/article/details/52788947 特征和指示特征 对数线性模型log linear model 对数线性模型有:最大熵模型和逻辑斯谛回归。 [概率图模型原理与技术] [PGM:无向图模型:马尔可夫网 ] 皮皮blog 最大熵模型的一般形式…

广义线性模型(Generalized Linear Model)之三:Poisson回归

广义线性模型(Generalized Linear Model)之三:Poisson回归 一、泊松回归(Poisson regression)简介(一)泊松回归(二)计数数据(三)泊松分布1&#x…

MIT自然语言处理第五讲:最大熵和对数线性模型

MIT自然语言处理第五讲:最大熵和对数线性模型(第一部分) 自然语言处理:最大熵和对数线性模型 Natural Language Processing: Maximum Entropy and Log-linear Models 作者:Regina Barzilay(MIT,EECS Depar…

机器学习教程 之 线性模型:线性回归、对数几率回归、线性判别分析

常用的三个线性模型的原理及python实现——线性回归(Linear Regression)、对数几率回归(Logostic Regression)、线性判别分析(Linear Discriminant)。 这可能会是对线性模型介绍最全面的博客 文章目录 一、…

机器学习(二)线性模型——线性回归、对数几率回归、线性判别分析

一、线性回归 线性回归(linear regression:试图学得一个线性模型以尽可能准确地预测实值输出标记。 1.最简单的形式:输入属性的数且只有一个, 最小二乘法:基于均方差误差最小化来进行模型的求解,在线性回…

对数线性模型:逻辑斯谛回归和最大熵模型

http://blog.csdn.net/pipisorry/article/details/52788947 对数线性模型log linear model 对数线性模型有:最大熵模型和逻辑斯谛回归。 特征和指示特征 对数线性模型的一般形式 [概率图模型原理与技术] 某小皮 对数线性模型的不同形式 因子图 将因子转换到对…

从线性到非线性模型-对数线性模型

从线性到非线性模型 1、线性回归,岭回归,Lasso回归,局部加权线性回归 2、logistic回归,softmax回归,最大熵模型 3、广义线性模型 4、Fisher线性判别和线性感知机 5、三层神经网络 6、支持向量机 code: https://…

论文总结3 对数线性模型 罗盛

研究变量之间的相互关系、列联表、对应分析 目录 一、模型介绍 二、比较-对数线性模型&对应分析 1.相同&不同 2.相互关系 三、应用实例 1.模型确立 2.列因素&因子负荷 四、总结经验 一、模型介绍 列联表分析无法系统地评价变量间的联系,无法…

对数线性模型之一(逻辑回归), 广义线性模型学习总结

经典线性模型自变量的线性预测就是因变量的估计值。 广义线性模型:自变量的线性预测的函数是因变量的估计值。常见的广义线性模型有:probit模型、poisson模型、对数线性模型等等。对数线性模型里有:logistic regression、Maxinum entropy。本篇是对逻辑回归的学习总结,以及…

机器学习篇——对数线性模型

建议首先看cs229讲的广义线性模型、exponential family(指数分布族) 对数线性模型包括逻辑回归、最大熵模型和条件随机场等 1、模型 条件概率分布(对数线性模型、概率模型)、判别模型 逻辑回归: 概率分布可由广…

对数线性模型(Logistic回归算法)

1.Logistic分布: logistic分布定义:设X是连续随机变量,X服从logistic分布,即为X具有下列分布函数和密度函数: 其中,mu为位置参数,r>0为形状参数; logistic分布的分布函数F(x)的…