Linux改用CFS调度器基于vruntime动态调度而非固定时间片,以实现按权重公平分配CPU时间;高nice值进程vruntime增长快、调度少,交互进程唤醒时vruntime被调低而优先运行。

Linux 不再用固定时间片分配 CPU,而是靠 CFS 调度器动态计算“虚拟运行时间(vruntime)”来决定谁该上 CPU。你看到的 top 里“正在运行”的进程,绝大多数其实没真在跑——只是被 CFS 选中、排在了当前就绪队列最前面而已。
为什么改用 vruntime 而不是固定时间片?
固定时间片(比如老内核的 10ms)在负载变化时很僵硬:交互任务要低延迟,CPU 密集型任务要高吞吐,一刀切会两头不讨好。CFS 的核心是让每个进程“公平地”获得与其权重匹配的 CPU 时间,数学上近似满足:w_i / Σw_j(w_i 是进程权重)。它不承诺“每 5ms 切一次”,而是持续追踪每个进程“本该运行多久了”,然后挑 vruntime 最小的那个上。
- 高
nice值(低优先级)→ 权重小 →vruntime增长快 → 更少被调度 - 刚唤醒的交互进程(如鼠标点击后唤醒的 GUI 线程)→
vruntime被主动调低 → 下次极大概率被立即选中 - 长时间霸占 CPU 的编译进程 →
vruntime持续飙升 → 自动让出机会
怎么查和调一个进程的实际调度行为?
别信 ps -o time 这种累计时间,它不反映调度粒度。要看真实调度节奏,得用:
-
pidstat -t -p:每秒输出线程级的1 %cpu和Priority,观察是否频繁被切走 -
chrt -p:确认当前策略(SCHED_NORMAL表示走 CFS)和实时优先级(普通进程为 0) -
cat /proc/:直接读内核调度结构体,/sched | grep -E "(vruntime|se\.sum_exec_runtime)" vruntime值越小越“饥饿”
注意:vruntime 是纳秒级数值,且不同 CPU 核心的 runqueue 独立维护,跨核迁移后会做补偿校准——所以绑核(taskset)后看到的 vruntime 才真正可比。
网奇.NET网络商城系统是基于.Net平台开发的免费商城系统。功能强大,操作方便,设置简便。无需任何设置,上传到支持asp.net的主机空间即可使用。系统特色功能:1、同时支持Access和SqlServer数据库;2、支持多语言、多模板3、可定制缺货处理功能4、支持附件销售功能5、支持会员组批发功能6、提供页面设计API函数7、支持预付款功能8、配送价格分地区按数学公式计算9、商品支持多类别,可
哪些操作会意外破坏 CFS 的公平性?
CFS 很聪明,但人为干预常让它“困惑”:
- 给多个 CPU 密集型进程设相同
nice值,却把它们全绑到同一颗 CPU 上 → 它们会按 vruntime 轮着跑,但上下文切换开销暴增(比如 nginx worker 数 > CPU 核数) - 用
chrt -f 99把后台任务设成 SCHED_FIFO → 它会彻底压过所有 CFS 进程,连 ssh 都可能卡住 - 在 NUMA 机器上只用
taskset绑核,却不配numactl --membind→ 进程在 CPU0 跑,数据却从远端内存取,延迟翻倍,CFS 以为它“慢”而多给时间片,实则浪费
CFS 的公平是带权重的动态平衡,不是平均主义。真正要调的不是“时间片大小”,而是进程的权重(nice)、执行位置(taskset/numactl)、甚至是否该脱离 CFS(比如硬实时必须用 SCHED_FIFO)。看 /proc/sys/kernel/sched_latency_ns 这类参数前,先确认你面对的是调度延迟问题,还是内存/IO/锁瓶颈——后者调啥都没用。









