linux-0.00任务切换,CPU上下文切换

本文详细解释了CPU上下文切换的概念及其对系统性能的影响。包括进程、线程及中断上下文切换的区别,以及如何通过系统工具监测上下文切换的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cpu上下文

在每个任务运行前,cpu 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 cpu 寄存器和程序计数器(program counter,pc)。

cpu 寄存器,是 cpu 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 cpu 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 cpu 在运行任何任务前,必须的依赖环境,因此也被叫做 cpu 上下文。

cpu 上下文切换

就是先把前一个任务的 cpu 上下文(也就是 cpu 寄存器和程序计数器)保存起来

加载新任务的上下文到这些寄存器和程序计数器

跳转到程序计数器所指的新位置,运行新任务。

根据任务的不同,cpu 的上下文切换就可以分为几个不同的场景,也就是进程上下文切换、线程上下文切换以及中断上下文切换。

进程和线程

进程是资源分配和执行的基本单位;线程是任务调度和运行的基本单位。线程没有资源,进程给指针提供虚拟内存、栈、变量等共享资源,而线程可以共享进程的资源。

进程上下文切换

linux 按照特权等级,把进程的运行空间分为内核空间和用户空间。

cpu 特权等级的 ring 0 和 ring 3。

内核空间(ring 0)具有最高权限,可以直接访问所有资源;用户空间(ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源。

进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。从用户态到内核态的转变,需要通过系统调用来完成。

一次系统调用的过程,其实是发生了两次 cpu 上下文切换。

线程上下文切换

线程的上下文切换其实就可以分为两种情况

前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样。

前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。

中断上下文切换

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

对同一个 cpu 来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会与进程上下文切换同时发生。同样道理,由于中断会打断正常进程的调度和执行,所以大部分中断处理程序都短小精悍,以便尽可能快的执行结束。

中断只会发生在内核态

查看中断类型

从/proc/interrupts 这个只读文件中读取。/proc 实际上是 linux 的一个虚拟文件系统,用于内核空间与用户空间之间的通信。/proc/interrupts 就是这种通信机制的一部分,提供了一个只读的中断使用情况。

vmstat

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

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)的次数。

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

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

总结

cpu 上下文切换,是保证 linux 系统正常工作的核心功能之一,一般情况下不需要我们特别关注。

但过多的上下文切换,会把 cpu 时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降。

上下文切换类型:

自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 i/o 等其他问题;

非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 cpu,说明 cpu 的确成了瓶颈;

中断次数变多了,说明 cpu 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值