CPU上下文切换,可能会导致CPU使用率的飙升,那当CPU到100%的时候,我们该如果定位是否是因为CPU上下文切换导致的呢?
可以通过vmstat、pidstat命令来查看。
# 每隔5秒输出1组数据
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 7005360 91564 818900 0 0 0 0 25 33 0 0 100 0 0
#r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
#b(Blocked)则是处于不可中断睡眠状态的进程数。
#cs(context switch)是每秒上下文切换的次数。
#in(interrupt)则是每秒中断的次数。
可以看到,这个例子中的上下文切换次数 cs 是 33 次,而系统中断次数 in 则是 25 次,而就绪队列长度 r 和不可中断状态进程数 b 都是 0。
如果要看每个进程更详细的情况,就要用到pidstat命令了,给命令加上-w参数就可以看到进程切换的情况了。
# 每隔5秒输出1组数据
$ pidstat -w 5
Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU)
08:18:26 UID PID cswch/s nvcswch/s Command
08:18:31 0 1 0.20 0.00 systemd
08:18:31 0 8 5.40 0.00 rcu_sched
#cswch/s:每秒自愿上下文切换
#nvcswch/s:每秒非自愿上下文切换
所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
所谓非自愿上下文切换,是指进程时间片已到等原因,系统强制调度,发生的切换。比如,大量进程都在争抢CPU,就容易发生非自愿上下文切换。
pidstat -w显示的是进程的数据指标,再加上-t会显示下属线程的数据指标。命令 pidstat -wt
如果因为终端,发生了上下文切换,可以详细分析中断的类型,通过查看/proc/interrupts文件,可以看出发生了哪些中断。
# -d 参数表示高亮显示变化的区域
$ watch -d cat /proc/interrupts
CPU0 CPU1
...
RES: 2450431 5279697 Rescheduling interrupts
...
RES(重调度中断),这个中断类型表示,唤醒空闲状态的 CPU 来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同 CPU 的机制,通常也被称为处理器间中断。
总结:
自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;
中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。