vmstat的cs列反映系统级上下文切换频率,空闲时通常1000–1500次/秒,持续超5000次/秒需警惕;但必须联动r(就绪队列)、b(阻塞进程)、in(中断)三列判断根因:r长期大于CPU核数指向非自愿切换,b升高提示I/O或锁等待引发的自愿切换,in与cs同步飙升表明中断风暴。

vmstat 的 cs 列就是你要的系统级上下文切换频率,但单看这个数字毫无意义——必须结合 r、b、in 三列联动判断根因。
怎么看 cs 值算高
空闲系统下 cs 通常在 1000–1500 次/秒;持续超过 5000 次/秒需警惕,但这不是硬阈值。关键要看业务基线:压测前后翻 2–3 倍,哪怕只到 4000,也值得深挖。
执行 vmstat 1 后,第一行是启动以来平均值,忽略它;从第二行开始才是实时数据,盯住每秒刷新的 cs 列。
-
r(就绪队列长度)长期大于 CPU 核数 → 非自愿切换主导,CPU 在被抢 -
b(阻塞进程数)同步升高 → 自愿切换主导,大概率 I/O 卡顿或锁争用 -
in(中断次数)和cs同步飙升 → 中断风暴,比如网卡收包过载,跟进程调度无关
为什么 vmstat cs 和所有进程 cswch/s + nvcswch/s 对不上
vmstat 的 cs 是内核全局计数器,包含三类事件:
- 进程/线程级切换(
pidstat -w统计的部分) - 硬件中断上下文切换(如磁盘、网卡触发的中断处理)
- 软中断上下文切换(如网络协议栈、定时器
softirq)
而 pidstat -w 只统计第一类,且不包括内核线程(如 ksoftirqd)和中断上下文。所以 vmstat cs 一定 ≥ 所有进程 cswch/s + nvcswch/s 总和——差值就是中断相关切换。
典型现象:pidstat -w 看不到高切换进程,但 vmstat cs = 12000 且 in = 11000 → 直接查 /proc/interrupts,别在用户进程里瞎找。
怎么避免把 cs 当成“CPU 使用率”误读
cs 高 ≠ CPU 忙,甚至可能和 us、sy 都低并存。例如:
- I/O 密集型任务:
cs高、b高、wa>10%、us很低 → 进程反复挂起/唤醒,CPU 其实空着 - 中断风暴:
cs高、in高、sy中等、r很低 → 内核忙于处理中断,用户进程没机会跑 - CPU 竞争:
cs高、r> 核数、us+sy接近 100%、id≈ 0 → 真正的调度过载
记住:cs 是“切换动作”的频次,不是“CPU 被占满”的证据。它告诉你系统在频繁保存/恢复上下文,但不告诉你这些上下文里跑的是什么。
实际排查时最容易忽略的一点
vmstat 1 输出中,cs 是全系统总和,它无法告诉你切换是否集中在某颗 CPU 上。比如 8 核机器 cs=8000,可能是 1 核扛了 7500 次,其余 7 核几乎空闲——这种不均衡问题,vmstat 完全看不见。真要定位单核瓶颈,得切到 pidstat -w -T ALL 看线程 psr 值,或用 perf record -e context-switches -a 按 CPU 分组采样。











