CPU 与调度60 条

schedstat 调度统计

开启 CONFIG_SCHEDSTATS 后可读 /proc/schedstat 与 /proc/<pid>/schedstat,观察运行时长、排队等待与迁移计数,验证调度行为。

什么是 schedstat

开启调度统计后,内核会记录每个任务的运行时长、在运行队列中的等待时长与获得时间片的次数,以及每个 CPU 的调度行为计数。进程级数据在 /proc/<pid>/schedstat(三个数字:运行纳秒、等待纳秒、时间片次数),系统级在 /proc/schedstat。它的用途是验证调度行为:例如判断进程虽然“在跑”但大部分时间花在排队,或者迁移频繁导致缓存失效率高。

基本信息

进程级/proc/<pid>/schedstat:运行 ns、等待 ns、时间片次数
系统级/proc/schedstat 每 CPU 一行
前提内核编译时开启调度统计(CONFIG_SCHEDSTATS)
开关较新内核可通过 /proc/sys/kernel/sched_schedstats 控制
相关文件/proc/<pid>/sched 的信息更丰富
适用调度行为验证与延迟归因

典型使用场景

  • 进程响应慢但 CPU 不忙:确认等待时间是否集中在运行队列排队
  • 验证调度策略调整:对比调整前后的等待时长占比
  • 容器与虚拟化环境:评估 CPU 争抢对单个任务的影响
  • 与 cgroup 的 CPU 统计交叉验证,确认配额与限流的影响
  • 排查迁移导致的开销:结合 /proc/<pid>/sched 中的迁移计数

查看与采样

查看与采样
cat /proc/$$/schedstat                 # 当前 shell 的三个计数
cat /proc/<pid>/schedstat              # 指定进程
cat /proc/sys/kernel/sched_schedstats  # 统计开关(部分内核提供)
awk 'NR>1 && NR<4' /proc/schedstat     # 系统级前几行
# 间隔采样看增量:
cat /proc/<pid>/schedstat; sleep 5; cat /proc/<pid>/schedstat
cat /proc/<pid>/sched | grep -i -E 'nr_switches|se.wait|migrations'

字段读法

字段含义判读要点
运行时间(ns)累计占用 CPU 的时间与进程 CPU 消耗对照
等待时间(ns)在运行队列中排队的时间占比高说明 CPU 资源紧张
时间片次数获得调度的次数过多说明频繁切换与被抢占
nr_switches上下文切换总数结合自愿/非自愿切换分开看
migrations迁移次数偏多时关注缓存与 NUMA 影响
字段含义随内核版本演进,解读前对照本机内核文档;不要照搬旧资料里的字段顺序,必要时以 /proc/<pid>/sched 的具名字段交叉验证。
部分发行版默认关闭该统计,文件存在但数值可能长期为 0;直接据此判断“没有调度等待”会得出错误结论。

易错点

  • 字段含义随版本演进,解读前对照本机内核文档,脚本按固定位置取数容易失效
  • 部分发行版默认关闭该统计项,文件存在但数值可能全为 0,需要先确认开关状态
  • 用累计值直接做结论而不做增量采样:这些数字是单调递增的,只有增量才有可比性
  • 把等待时间高直接等同于 CPU 不够,也可能来自频繁的锁等待或 IO 阻塞,要结合上下文切换一起看

数据来源与参考

  • Linux 内核 Documentation/scheduler/sched-stats.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌