Linux CFS(完全公平调度器)全面总结

  1. 核心设计理念

基本目标

• 完全公平:按权重而非绝对时间分配CPU份额

• 低开销:调度决策高效,适合大规模任务

• 良好响应性:保证交互式任务及时响应

公平性定义

• 公平 = 每个任务获得与其权重成比例的CPU时间

• 高优先级任务(低nice值)获得更多CPU时间

• 防止任何任务饿死

  1. 核心机制:虚拟运行时(vruntime)

vruntime计算

vruntime_increase = 实际运行时间 × (NICE_0_LOAD / 任务权重)

• 普通优先级任务:vruntime ≈ 实际运行时间

• 高优先级任务:vruntime增长更慢

• 低优先级任务:vruntime增长更快

vruntime的意义

• 衡量任务"已消耗的公平份额"

• vruntime越小,表示"吃亏"越多,优先级越高

• 调度目标:让所有任务的vruntime尽可能同步

  1. 数据结构与调度算法

红黑树管理

• 键值:任务的vruntime

• 最左节点:vruntime最小的任务,下一个被调度

• 操作效率:插入、删除、查找均为O(logN)

调度过程

  1. 选择任务:从红黑树取最左节点(vruntime最小)

  2. 任务运行:在CPU上执行

  3. 时间统计:更新实际运行时间和vruntime

  4. 重新插入:任务放回红黑树(如果仍可运行)

  5. 选择下一个:重复步骤1

  6. 时间管理与调度周期

关键参数

• sched_latency_ns:目标调度周期(默认24ms)

• sched_min_granularity_ns:最小时间片(默认3ms)

动态时间片计算

时间片 = max(调度周期/N, 最小时间片)

• 任务少时:每个任务获得较长时间片

• 任务多时:保证所有任务都能在周期内运行

  1. 任务状态处理

新任务创建

• vruntime初始化为当前运行队列的min_vruntime

• 给予适当补偿,避免过度"插队"

睡眠任务唤醒

• 关键机制:vruntime补偿 = -sched_latency_ns/2

• 目的:提升交互式任务响应性,但不破坏公平性

• 补偿值固定:不随任务数变化,保证最小响应性

实时进程关系

• 调度类优先级:RT > CFS > Idle

• 实时进程:总是抢占普通CFS任务

• 独立队列:实时进程使用优先级数组,CFS使用红黑树

  1. 多核与负载均衡

CPU间迁移

• vruntime调整:新vruntime = 原vruntime - 源CPUmin_vruntime + 目标CPUmin_vruntime

• 保持公平:迁移后维持相对进度位置

• 防止蜂拥:迁移不会获得不公平优势

负载均衡触发

• 周期性检查(每1-10ms)

• 新任务创建

• 任务唤醒

• CPU空闲时

  1. 抢占机制

调度触发点

  1. 主动调度:系统调用、阻塞操作
  2. 时钟中断:周期性检查(tick机制)
  3. 实时抢占:高优先级实时任务就绪
  4. 唤醒抢占:睡眠任务唤醒时可能抢占

完全抢占支持

• CONFIG_PREEMPT:允许内核态抢占

• 关键区域保护:持有自旋锁时不可抢占

• 中断返回路径:实际调度发生点

  1. 实际表现特性

优点

• ✅ 真正公平:按权重精确分配CPU时间

• ✅ 高扩展性:红黑树支持大量任务高效调度

• ✅ 良好响应性:交互式任务获得优先处理

• ✅ 自适应:动态调整时间片,平衡延迟和吞吐量

可调参数

查看和调整调度参数

/proc/sys/kernel/sched_latency_ns

/proc/sys/kernel/sched_min_granularity_ns

/proc/sys/kernel/sched_migration_cost_ns

  1. 总结

CFS是Linux调度器的重大进步,通过vruntime机制实现了真正的公平性:

• 核心创新:用vruntime替代传统时间片

• 高效实现:红黑树保证调度决策高效

• 公平保证:权重机制确保按比例分配CPU

• 响应性保障:睡眠补偿和完全抢占机制

• 多核优化:负载均衡和vruntime迁移保持跨CPU公平

这种设计使Linux能够同时满足服务器的高吞吐量和桌面的交互性需求,是现代操作系统调度算法的典范。

相关推荐
米高梅狮子7 小时前
11. Linux 防火墙管理
linux·运维·服务器
专注VB编程开发20年7 小时前
c#Type数组转成字符串的名称
java·开发语言
中年程序员一枚8 小时前
多数据源的springboot进行动态连接方案
java·spring boot·后端
w***76558 小时前
SpringBoot集成MQTT客户端
java·spring boot·后端
若风的雨8 小时前
RC-EP 和 Switch-EP 的复位链路建立过程区别
linux
HABuo8 小时前
【Linux进程(五)】进程地址空间深入剖析-->虚拟地址、物理地址、逻辑地址的区分
linux·运维·服务器·c语言·c++·后端·centos
编程饭碗8 小时前
【多线程编程】
java·开发语言
开开心心_Every8 小时前
安卓做菜APP:家常菜谱详细步骤无广简洁
服务器·前端·python·学习·edge·django·powerpoint
wdfk_prog8 小时前
WIN11如何可以安装ISO
linux·笔记·学习
旖旎夜光8 小时前
Linux(10)(中)
linux