当前位置:首页 > 数据库

怒啃 24 小时,终于搞懂上下文切换!

​大家好 ,怒啃我是终于树哥。

对于服务器系统来说 ,搞懂上下文切换也是上下影响系统性能的一个重要因素 。深入理解上下文切换的文切原理 ,有利于我们做好性能优化工作。怒啃今天我将带大家了解下上下文切换的终于几种情形 ,以及其背后发生切换的搞懂具体信息 ,接着介绍一些监测上下文切换指标的上下工具 ,最后总结一些上下文切换异常可能得场景。建站模板文切

深入理解系统上下文切换

什么是怒啃上下文切换?

我们知道 Linux 是一个多任务操作系统,它能支持远大于 CPU 数量的终于任务同时运行  。但实际上同一时刻只会有 CPU 数量的搞懂进程在运行 ,等 CPU 时间片到了之后,上下进程调度器就会把 CPU 资源分配给其他进程 。文切

在这个过程中就会涉及到进程之间的切换 ,这时候就需要将当前进程的上下文信息保存下来 ,随后加载被调度进程的上下文信息 ,这就是源码下载上下文切换。

这里所说的上下文信息 ,既包括虚拟内存 、栈、全局变量等用户态的资源,也包括内核堆栈 、寄存器等内核态的资源。不同类型的上下文切换 ,会涉及到不同类型资源的切换,例如:同一进程不同线程的切换,服务器租用只需要切换内核态的资源,而不需要切换用户态的资源。

上下文切换类型

上下文还分为了三种类型 ,分别是 :

进程上下文切换线程上下文切换中断上下文切换

进程上下文切换

进程上下文切换指的是不同进程之间发生切换 。一般来说 ,进程被调度有如下几个时机 :

某个进程时间片耗尽,会被系统挂起 ,切换到其他等待 CPU 的进程。进程所需系统资源不足,需要等到资源满足时才可运行 ,云计算此时会被挂起,其他进程会被调度。进程通过 sleep 方法主动挂起 ,其他进程就有机会被调度 。有更高优先级的进程 ,当前进程会被挂起 ,高优先级进程会被调度 。硬件中断时 ,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序。

当发生如上几种情况的时候,就会发生进程调度,免费模板进而发生进程上下文切换 。

线程上下文切换

我们都知道进程是资源分配的基本单位 ,线程是调度的基本单位 ,进程只是给线程提供了虚拟内存等资源 。而线程上下文切换  ,就可以分为两种情况 :

进程调度前后的两个线程,属于同一进程。此时因为资源共享 ,所以在切换的时候虚拟内存等这些资源就不需要变化 ,源码库只需要切换线程的私有数据、寄存器等不共享的数据。进程调度前后的两个线程,不属于同一进程。这时候因为资源部共享,所以切换过程和进程上下文切换是一样的。

所以你会发现同进程内的线程切换,要比多进程间的切换消耗更少的资源,这其实就是多线程比起多进程的一个优势 。

中断上下文切换

中断上下文切换指的是为了响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序 ,响应设备事件 。而在打断其他进程时,就需要将当前的状态保存下来。这样在中断结束后,进程仍然可以从原来的状态恢复运行 。

中断上下文切换 ,并不需要保存和恢复进程的虚拟内存等用户态资源 ,只需要处理 CPU 寄存器 、内核堆栈等内核态的资源即可 。

分析工具

查看系统的上下文切换情况 ,有三个工具可以使用  ,分别是  :vmstat​ 命令、pidstat​ 命令、/proc/interrupts 文件 。

vmstat 命令

vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况 ,也常用来分析 CPU 上下文切换和中断的次数。该命令的语法格式为:

复制vmstat <选项> <时间间隔> <报告次数>1.

其中常用的选项有 :

-a :显示活动内页;-f :显示启动后创建的进程总数;-m :显示 slab 信息;-n :头信息仅显示一次;-s:以表格方式显示事件计数器和内存状态;-d :报告磁盘状态;-p :显示指定的硬盘分区状态;-S:输出信息的单位。

我们执行 vmstat 5 命令后,会每隔 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 6893400 2352 563768 0 0 2 425 153 32 1 3 96 0 01.2.3.

其中与上下文相关的 4 列内容如下:

cs(context switch)是每秒上下文切换的次数 。in(interrupt)则是每秒中断的次数 。r(Running or Runnable)是就绪队列的长度  ,也就是正在运行和等待 CPU 的进程数。b(Blocked)则是处于不可中断睡眠状态的进程数 。

可以看到上面输出中上下文切换次数 cs 是 32 次,而系统中断次数 in 是 153 次,而就绪队列长度 r 和不可中断状态进程数 b 都是 0  。

pidstat 命令

vmstat 只给出了系统总体的上下文切换情况 ,要想查看每个进程的详细情况 ,就需要使用我们前面提到过的 pidstat 了。给它加上 -w 选项,你就可以查看每个进程上下文切换的情况了。 例如执行如下命令 ,我们可以得到每个进程的上下文切换情况了 。

复制// 每隔 5

秒输出一次结果

// -

w 表示显示每个进程的上下文切换情况

[root@iZwz92ezhi90syoqbgjgn1Z ~]# pidstat -w 5Linux 4.18.0-348.7.1.el8_5.x86_64 (iZwz92ezhi90syoqbgjgn1Z) 23/08/22 _x86_64_ (4 CPU)15:04:39 UID PID cswch/s nvcswch/

s Command

15:04:44 0 1 0.20 0.00

systemd

15:04:44 0 11 27.94 0.00

rcu_sched

15:04:44 0 497 19.56 0.00 xfsaild/

vda3

15:04:44 0 603 0.20 0.00 systemd-

journal

15:04:44 0 829 0.40 0.00

sssd_be

15:04:44 0 831 1.60 0.00

sssd_nss

15:04:44 0 3931 0.40 0.00 kworker/2:0-

mm_percpu_wq

15:04:44 0 3998 0.40 0.00 kworker/1:0-

mm_percpu_wq

15:04:44 0 4005 0.20 0.00 kworker/u8:0-flush-253:015:04:44 0 4021 0.80 0.00 kworker/3:2-

mm_percpu_wq

15:04:44 0 4037 5.99 0.00 kworker/0:0-events1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.

上述结果中的 cswch 与 nvcswch 是重点关注的对象。cswch 表示每秒自愿上下文切换(voluntary context switches)的次数  ,nvcswch 表示每秒非自愿上下文切换(non voluntary context switches)的次数。

所谓自愿上下文切换 ,是指进程无法获取所需资源 ,导致的上下文切换 。比如说 , I/O 、内存等系统资源不足时 ,就会发生自愿上下文切换。

而非自愿上下文切换,则是指进程由于时间片已到等原因  ,被系统强制调度,进而发生的上下文切换。比如说 ,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换 。

/proc/interrupts 文件

我们可以通过 vmstat 获取中断的次数 ,但是我们却无法获取中断类型。实际上我们可以通过 /proc/interrupts​ 文件获取中断的详细信息。/proc​ 实际上是 Linux 的一个虚拟文件系统 ,用于内核空间与用户空间之间的通信。/proc/interrupts 就是这种通信机制的一部分,提供了一个只读的中断使用情况 。

我们可以通过如下命令 ,动态观察中断的变化情况:

复制# -

d 参数表示高亮显示变化的区域

$ watch -d cat /proc/

interrupts

CPU0 CPU1

...

RES: 4385721 4430589 3732298 4259089

Rescheduling interrupts

...1.2.3.4.5.6.

通过这种方式 ,我们就可以知道具体是哪种中断类型出现异常 ,从而定位到具体的资源 。

如何排查异常 ?

今天我们深入了解了一下上下文切换这个指标,但每秒上下文切换多少次才算正常呢 ?

这个数值取决于系统本身的 CPU 性能。如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的 。但当上下文切换次数超过一万次,或者切换次数出现数量级的增长时 ,就很可能已经出现了性能问题 。

具体遇到问题的时候 ,需要根据变化的上下文切换类型,再做具体的分析。例如  :

自愿上下文切换变多了,说明进程都在等待资源 ,有可能发生了 I/O 等其他问题。非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈。中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型  。总结

首先,我们先介绍了上下文切换的概念,以及上下文切换可能会包含用户态资源和内核态资源 。

接着,我们介绍了三种上下文切换类型,即:进程上下文切换、线程上下文切换、中断上下文切换,并分析其切换包括的资源类型。

接着,我们介绍了 vmstat​ 命令  、pidstat​ 命令 、/proc/interrupts​ 三种分析工具 。其中 vmstat​ 命令用户查看系统整体上下文切换情况 ,pidstat​ 命令用户查看进程的上下文切换情况,/proc/interrupts 文件用户查看中断类型及详细情况 。

最后,解释了合理的上下文切换次数应该是数百到一万每秒以内。但具体的问题排查 ,还需要根据上下文切换类型去分析。

参考资料

03 | 基础篇:经常说的 CPU 上下文切换是什么意思 ?(上)

04 | 基础篇  :经常说的 CPU 上下文切换是什么意思 ?(下)

vmstat 命令,Linux vmstat 命令详解:显示虚拟内存状态 - Linux 命令搜索引擎

分享到:

滇ICP备2023000592号-28