欢迎光临
我们一直在努力

Linux CPU 时间片是如何分配的?

RackNerd Leaderboard Banner RackNerd Leaderboard Banner

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

Linux 不再用固定时间片分配 CPU,而是靠 CFS 调度器动态计算“虚拟运行时间(vruntime)”来决定谁该上 CPU。你看到的 top 里“正在运行”的进程,绝大多数其实没真在跑——只是被 CFS 选中、排在了当前就绪队列最前面而已。

改用 vruntime 而不是固定时间片?

固定时间片(比如老内核的 10ms)在负载变化时很僵硬:交互任务要低延迟,CPU 密集型任务要高吞吐,一刀切会两头不讨好。CFS 的核心是让每个进程“公平地”获得与其权重匹配的 CPU 时间,数学上近似满足:w_i / Σw_jw_i 是进程权重)。它不承诺“每 5ms 切一次”,而是持续追踪每个进程“本该运行多久了”,然后挑 vruntime 最小的那个上。

  • nice 值(低优先级)→ 权重小 → vruntime 增长快 → 更少被调度
  • 刚唤醒的交互进程(如鼠标点击后唤醒的 GUI 线程)→ vruntime 被主动调低 → 下次极大概率被立即选中
  • 长时间霸占 CPU 的编译进程 → vruntime 持续飙升 → 自动让出机会

怎么查和调一个进程的实际调度行为?

别信 ps -o time 这种累计时间,它不反映调度粒度。要看真实调度节奏,得用:

  • pidstat -t -p 1 :每秒输出线程级的 %cpuPriority,观察是否频繁被切走
  • chrt -p :确认当前策略(SCHED_NORMAL 表示走 CFS)和实时优先级(普通进程为 0)
  • cat /proc/ /sched | grep -E "(vruntime|se\.sum_exec_runtime)" :直接读内核调度结构体,vruntime 值越小越“饥饿”

注意:vruntime 是纳秒级数值,且不同 CPU 核心的 runqueue 独立维护,跨核迁移后会做补偿校准——所以绑核(taskset)后看到的 vruntime 才真正可比。

css3立体相册突出效果,这样的效果还是很漂亮的,相册的效果大部分用于个人网站或者qq空间这样的网页里面,可以下载下来,换一些自己的图片,看效果如何!

哪些操作会意外破坏 CFS 的公平性?

CFS 很聪明,但人为干预常让它“困惑”:

  • 给多个 CPU 密集型进程设相同 nice 值,却把它们全绑到同一颗 CPU 上 → 它们会按 vruntime 轮着跑,但上下文切换开销暴增(比如 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/锁瓶颈——后者调啥都没用。

RackNerd Leaderboard Banner
未经允许不得转载:国外主机测评 » Linux CPU 时间片是如何分配的?