由于Linux是一个多任务操作系统,能够支持远大于CPU数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是由CPU进行调度,将时间分片,每个任务占用1个时间片,通过轮流的方式运行,但由于时间片粒度非常小,而CPU速度非常高,造成多任务同时运行的错觉。实际上,对于单个CPU核,其处理数据是串行的,就比如做核酸检测,只有一个检测口,组织人员会在检测口排几个队列,每个队列头部数出10个人构成一组。检测口就相当于CPU,无论怎么排队,所有人都得经过检测口,它的工作量一点没有变。但是各队列中的10人小组是轮换的,这样稍微增加一些效率(减少了数10个人的时间),保证了公平性(每个队列都是等同的,大家随便排到哪个队列里),如果检测速度非常快,那么单个队列里的各10个人小组可能并不觉得有另外几个队列的存在。对于多队列多CPU核的情况就复杂了,这里不讨论了。

在每个任务(进程、线程、中断)运行前,CPU都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU寄存器和程序计数器。以核酸检测为例,每个队列都有一个编号,从1-N;每个队列里的人都有一个号码,从1到K,但每个人胖瘦不同、检测耗时不同;核酸检测的时候,组织人员得知道下一次到了那个队列的哪个人员(这里假设做完核酸的人员还回到队列里)。如果组织人员不维护队列号码和队列内部的人员编号,那么整个过程将会混乱不堪。而组织人员做的事情就是给CPU的各寄存器装订正确的参数。这里面,队列就相当于任务,人员就相当于指令。
什么是CPU上下文
CPU寄存器和程序计数器(也是一个寄存器)就是CPU上下文,因为它们都是CPU在运行任何任务前,必须的依赖环境。也就是上面的队列ID和人员编号。
- CPU寄存器是CPU内置的容量小、但速度极快的内存。
- 程序计数器则是用来存储CPU正在执行的指令位置、或者即将执行的下一条指令位置。
什么是CPU上下文切换
就是先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务的过程。
而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。
CPU上下文切换的类型
根据任务的不同,可以分为以下三种类型:
- 进程上下文切换
- 线程上下文切换
- 中断上下文切换
进程上下文切换
Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,CPU特权等级的Ring0和Ring3。
- 内核空间(Ring0)具有最高权限,可以直接访问所有资源;
- 用户空间(Ring3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源。
进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。
系统调用
从用户态到内核态的转变,需要通过系统调用来完成。比如,当我们查看文件内容时,就需要多次系统调用来完成:首先调用open()打开文件,然后调用read()读取文件内容,并调用write()将内容写到标准输出,最后再调用close()关闭文件。
在这个系统调用的执行过程中就发生了CPU上下文切换,整个过程是这样的:
- 保存CPU寄存器里原来用户态的指令位置(这部分代码是用户写的,通俗地讲就是下一个要执行的用户代码行号);
- 为了执行内核态代码,(这部分代码不是用户写的,而是linux内核中的代码)CPU寄存器需要更新为内核态指令的新位置(内核代码的行号?);
- 跳转到内核态运行内核任务;
- 当系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。
所以,一次系统调用的过程,其实是发生了两次CPU上下文切换。(用户态-内核态-用户态)
不过,需要注意的是,系统调用过程中,并不会涉及到虚拟内存等进程用户态的资源,也不会切换进程。这跟我们通常所说的进程上下文切换是不一样的:进程上下文切换,是指从一个进程切换到另一个进程运行;而系统调用过程中一直是同一个进程在运行。
所以,系统调用过程通常称为特权模式切换,而不是上下文切换。系统调用属于同进程内的CPU上下文切换。但实际上,系统调用过程中,CPU的上下文切换还是无法避免的。
发生进程上下文切换的场景
为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其它正在等待 CPU

本文详细介绍了Linux系统中CPU上下文切换的概念,包括进程上下文切换、线程上下文切换和中断上下文切换,以及它们在系统中的作用和影响。上下文切换涉及到CPU寄存器、程序计数器等状态的保存和恢复,频繁的上下文切换可能导致系统性能下降。中断机制是系统响应外部事件的方式,中断处理程序在内核态执行,中断上下文切换不涉及用户态资源。通过vmstat和pidstat等工具可以监控上下文切换和中断情况,过高次数可能表明系统存在性能问题。
最低0.47元/天 解锁文章
2567





