非常棒的问题!你想了解 现代 Linux 中的任务调度算法,这是深入理解内核如何公平、高效管理 CPU 的关键部分。
🎯 总览:现代 Linux 使用的调度器是 CFS(Completely Fair Scheduler)
自 Linux 2.6.23 起,CFS 取代了旧的 O(1) 调度器,成为主流 Linux 的默认调度器。
✅ 1. Linux CFS(完全公平调度器)
CFS 的目标是:让所有进程尽可能“公平”地分享 CPU 时间
🧠 CFS 的核心思想:
- 每个进程有一个 虚拟运行时间 vruntime
- 谁的
vruntime
最小,谁最“该被调度”,先执行 - 当进程使用 CPU,它的
vruntime
就增加,跑得越久,优先级越低 nice
值(静态优先级)会调整加权因子,影响vruntime
增速
🧱 数据结构:
CFS 使用 红黑树(Red-Black Tree) 管理所有可运行进程:
rbtree<vruntime, task_struct>
- 根节点是
vruntime
最小的进程 - 每次调度从红黑树取最左侧节点(即
vruntime
最小者)
🧮 调度公式简化理解:
vruntime += delta_exec * (NICE_WEIGHT / default_weight)
delta_exec
:本次执行时间NICE_WEIGHT
:nice 值换算出来的权重
✅ 2. 补充:其他调度策略类(调度类)
Linux 支持 多个调度类,CFS 是默认类,还有:
策略 | 名称 | 类型 | 用途 |
---|---|---|---|
SCHED_NORMAL | 普通进程使用的 CFS | 抢占式 | 默认调度策略 |
SCHED_BATCH | 后台任务 | 抢占式 | 非交互任务,调度延迟大但公平性好 |
SCHED_IDLE | 低优先级后台任务 | 抢占式 | 几乎不抢 CPU |
SCHED_FIFO | 实时任务(先来先服务) | 非抢占 | 用于实时系统 |
SCHED_RR | 实时任务(轮询) | 抢占式 | 固定时间片,实时性高 |
SCHED_DEADLINE | 实时任务(带时限) | EDF | Linux 实时补丁 PREEMPT_RT 下使用 |
✅ 3. 实时调度(FIFO / RR)
适合低延迟、确定性系统,如音频、工业控制:
SCHED_FIFO
:谁先来谁先得,不会被抢占SCHED_RR
:固定时间片轮转,但优先级一样的进程轮询执行
✅ 4. Deadline Scheduling(实时 deadline 调度)
Linux 3.14 引入的高级调度器:
Earliest Deadline First(EDF)+ Constant Bandwidth Server(CBS)组合调度算法
- 每个任务可指定:
runtime
: 每周期可用 CPU 时间period
: 时间周期deadline
: 最迟完成时间
- Linux 会确保该任务按 deadline 内完成!
用法:
chrt -d -T <runtime> -P <period> ./my_rt_task
✅ 5. 多核/NUMA 支持
现代 Linux 在调度时还要考虑:
- 多核间负载均衡
- CPU 亲和性(cpu affinity)
- NUMA 结构下的本地访问最优
有专门的 load balancer 负责定期在不同 CPU 核之间迁移任务
✅ 总结一句话:
现代 Linux 使用 CFS(完全公平调度器) 作为默认进程调度算法,结合红黑树管理
vruntime
,让所有进程“尽可能公平”使用 CPU,同时也支持一系列 实时调度策略(FIFO、RR、Deadline),适配从桌面到工业控制的多种应用场景。
如果你想深入了解:
- CFS 红黑树结构怎么实现的?
vruntime
在调度中如何更新?- 手写一个 toy 内核的 CFS 简化版?
- 或者给你举一个如何在用户态模拟调度器的示例?
我可以接着带你深入!🧠