CPU上下文
上下文是CPU在运行任务前的依赖环境,包括:
- CPU寄存器:CPU内置容量小、速度快的内存;
- 程序计数器:是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。
CPU 上下文切换
就是先把前一个任务的 CPU 上下文保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。场景
进程上下文切换、线程上下文切换以及中断上下文切换。线程是调度的基本单位,而进程则是资源拥有的基本单位;进程与线程关系类似于pod与容器。
进程上下文切换
只有在进程调度的时候,才需要切换上下文。Linux 为每个 CPU 都维护了一个就绪队列,将活跃进程按照优先级和等待 CPU 的时间排序,然后选择最需要 CPU 的进程,也就是优先级最高和等待 CPU 时间最长的进程来运行。
什么时候切换
- 进程执行完终止;
- 进程的时间片耗尽;
- 进程在系统资源不足时需要等到满足后才能运行,此时会被挂起;
- 进程使用睡眠函数sleep时会主动挂起;
- 当有优先级更高的进程运行时,当前进程会被挂起。
线程上下文切换
线程的上下文切换其实就可以分为两种情况:
- 第一种, 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样。
- 第二种,前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。
中断上下文切换
为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。消耗
根据 Tsuna 的测试报告,每次上下文切换都需要几十纳秒到数微秒的 CPU 时间。在进程上下文切换次数较多的情况下,很容易导致 CPU 将大量时间耗费在寄存器、内核栈以及虚拟内存等资源的保存和恢复上,进而大大缩短了真正运行进程的时间。
问题
- CPU在分配时间时,单线程的进程和双线程的进程使用CPU的时间一样吗?
- 进程与线程的上下文切换有什么不同?
进程包含线程,进程切换的同时也发生了线程切换,线程切换不一定发生进程切换。