「」Linux 是如何调度进程的?( 二 )


虚拟时间 = 实际时间 * (1024/进程权重) = (调度周期 * 进程权重 / 所有进程总权重) * (1024 / 进程权重) = 调度周期 * 1024 / 所有进程总权重
可以看出虽然进程的权重不同 , 但是它们的 vruntime增长速度应该是一样的, 与权重无关 。(进程A的虚拟时间=6.66 *(1024/1024)= 6.66ms , 进程B的虚拟时间=5.34 *(1024/820)= 6.66ms 。这里我们看出虽然进程的优先级不同 , 但最终的虚拟时间一样 。)
总结:谁的vruntime值较小就说明它当前占用cpu的时间较短 , 受到了“不公平”对待 , 因此下一个运行进程就是它 。这样既能公平选择进程 , 又能保证高优先级进程获得较多的运行时间 。这就是CFS的主要思想了 。
就绪队列(runqueue):
CFS维护了一个按照虚拟时间排序的红黑树:
「」Linux 是如何调度进程的?
文章图片

文章图片

任务存储在以时间为顺序的红黑树中(由 sched_entity 对象表示) , 对处理器需求最多的任务 (最低虚拟运行时)存储在树的左侧 , 处理器需求最少的任务(最高虚拟运行时)存储在树的右侧 。为了公平 , 调度器然后选取红黑树最左端的节点调度为下一个以便保持公平性 。任务通过将其运行时间添加到虚拟运行时 ,说明其占用 CPU 的时间 , 然后如果可运行 , 再插回到树中 。这样 , 树左侧的任务就被给予时间运行了 , 树的内容从右侧迁移到左侧以保持公平 。因此 , 每个可运行的任务都会追赶其他任务以维持整个可运行任务集合的执行平衡 。


推荐阅读