在每一个任务运行前,CPU 都须要知道任务从哪里加载、又从哪里开始运行,也就是说,须要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)。工具
CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任务前,必须的依赖环境,所以也被叫作 CPU 上下文。性能
根据任务的不一样,CPU 的上下文切换就能够分为几个不一样的场景,也就是进程上下文切换、线程上下文切换以及中断上下文切换。线程
进程是资源分配和执行的基本单位;线程是任务调度和运行的基本单位。线程没有资源,进程给指针提供虚拟内存、栈、变量等共享资源,而线程能够共享进程的资源。指针
Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间。
CPU 特权等级的 Ring 0 和 Ring 3。
内核空间(Ring 0)具备最高权限,能够直接访问全部资源;用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须经过系统调用陷入到内核中,才能访问这些特权资源。code
进程既能够在用户空间运行,又能够在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。从用户态到内核态的转变,须要经过系统调用来完成。队列
一次系统调用的过程,实际上是发生了两次 CPU 上下文切换。进程
线程的上下文切换其实就能够分为两种状况事件
为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其余进程时,就须要将进程当前的状态保存下来,这样在中断结束后,进程仍然能够从原来的状态恢复运行。内存
对同一个 CPU 来讲,中断处理比进程拥有更高的优先级,因此中断上下文切换并不会与进程上下文切换同时发生。一样道理,因为中断会打断正常进程的调度和执行,因此大部分中断处理程序都短小精悍,以便尽量快的执行结束。资源
中断只会发生在内核态
从/proc/interrupts 这个只读文件中读取。/proc 其实是 Linux 的一个虚拟文件系统,用于内核空间与用户空间之间的通讯。/proc/interrupts 就是这种通讯机制的一部分,提供了一个只读的中断使用状况。
vmstat 是一个经常使用的系统性能分析工具,主要用来分析系统的内存使用状况,也经常使用来分析 CPU 上下文切换和中断的次数。
// 5s 输出间隔 [root@k8s ~]# 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 4 0 0 1150604 194172 2888576 0 0 4 238 77 35 61 3 36 0 0 2 0 0 1147236 194172 2888812 0 0 0 96 3977 4630 69 4 27 0 0
cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
b(Blocked)则是处于不可中断睡眠状态的进程数。
pidstat给它加上 -w 选项,就能够查看每一个进程上下文切换的状况了。
// -w参数表示输出进程切换指标,而-u参数则表示输出CPU使用指标 // pidstat 默认显示进程的指标数据,加上 -t 参数后,才会输出线程的指标。 pidstat 5 -w -u Linux 3.10.0-1062.4.1.el7.x86_64 (instance-010oj085) 04/04/2020 _x86_64_ (2 CPU) 04:49:06 PM UID PID cswch/s nvcswch/s Command 04:49:11 PM 0 1 0.20 0.00 systemd 04:49:11 PM 0 6 1.20 0.00 ksoftirqd/0
cswch,表示每秒自愿上下文切换(voluntary context switches)的次数,nvcswch,表示每秒非自愿上下文切换(non voluntary context switches)的次数。
上下文切换类型: