OS 中的上下文切换 (Operating System)

2025年5月31日 | 阅读 14 分钟

你是否曾想过,为什么你的电脑或手机能够同时运行多个应用程序——比如在浏览网页,同时在后台下载文件,播放音乐?即使大多数电脑只有一个处理器(或类似设备),它们也能同时处理许多事情。这是因为一种叫做“上下文切换”的机制。

上下文切换是操作系统的一项功能,它允许操作系统在不同的任务或程序之间快速切换。它通过停止一个任务,保存其信息,然后启动另一个任务来实现。这个过程非常快,以至于看起来所有事情都在同时进行。

在本文中,我们将用简单易懂的语言解释什么是上下文切换,它是如何工作的,为什么它很重要,以及它如何影响你的计算机性能。

什么是上下文切换?

上下文切换是计算机操作系统将 CPU 从一个功能(或过程/线程)切换到另一个功能的过程。这使得许多程序能够同时运行,即使只有一个处理器。

每个正在运行的程序或进程都包含一个上下文,其中包含了 CPU 跟踪该进程的所有信息——例如其当前状态(程序计数器)、寄存器中的数据以及寄存器数据的用法。

当操作系统决定停止一个进程的运行并启动第二个进程时(例如,因为第一个进程正在等待输入或其时间片已到),它会执行以下几个阶段:

保存当前正在运行进程的上下文(状态)。

加载下一个要运行进程的上下文。

将控制权转交给新进程,使其可以从中断的地方继续执行。

整个过程称为上下文切换。

尽管每一次切换只花费几微秒,但高效地完成它却非常重要——因为如果花费太多时间在任务切换上,实际用于执行任务的时间就会减少。

上下文切换是操作系统用于将进程从一种状态切换到另一种状态以使用系统中的 CPU 来执行其功能的一种技术或方法。当系统执行切换时,它会以寄存器的形式存储旧进程的状态,并将 CPU 分配给新进程以执行其任务。在新进程运行时,前一个进程必须在就绪队列中等待。旧进程的执行将从另一个进程停止它的地方开始。它定义了多任务操作系统的一个特性,即多个进程共享同一个 CPU 来执行多个任务,而无需额外的处理器。

上下文切换的必要性

上下文切换有助于跨所有进程共享单个 CPU 以完成其执行,并存储系统的任务状态。当进程在系统中重新加载时,进程将从冲突发生的地方开始执行。

以下是描述操作系统中上下文切换必要性的原因。

  1. 系统中进程之间的切换不是直接进行的。上下文切换有助于操作系统在多个进程之间切换,以利用 CPU 资源来完成其任务并存储其上下文。我们可以稍后在同一地点恢复进程的服务。如果我们不存储当前正在运行进程的数据或上下文,那么在进程切换时存储的数据可能会丢失。
  2. 如果一个高优先级进程进入就绪队列,当前正在运行的进程将被该高优先级进程中断或停止,以便其在系统中完成任务。
  3. 如果任何正在运行的进程在系统中需要 I/O 资源,当前进程将被另一个进程切换出去以使用 CPU。当 I/O 需求得到满足后,旧进程将进入就绪状态,等待在 CPU 上执行。上下文切换会保存进程的状态,以便在操作系统中恢复其任务。否则,进程需要从初始级别重新开始执行。
  4. 如果在操作系统中运行进程时发生任何中断,进程状态将通过上下文切换以寄存器的形式保存。在解决中断后,进程将从等待状态切换到就绪状态,以便稍后在发生中断的地方恢复执行。
  5. 上下文切换允许单个 CPU 同时处理多个进程请求,而无需任何额外的处理器。

上下文切换的类型

1. 进程上下文切换

当操作系统将 CPU 从一个过程切换到另一个完全不同的进程时,会发生进程上下文切换。由于每个进程都在自己的内存空间中运行并拥有自己的资源集,因此这种切换需要保存和加载大量信息。这包括 CPU 寄存器、程序计数器、内存映射和其他进程控制数据。因此,进程切换相对耗时且资源密集。在运行许多独立程序的系统中很常见,例如在浏览器和媒体播放器之间切换。

2. 线程上下文切换

当 CPU 在同一进程内的不同线程之间切换时,会发生线程上下文切换。与进程不同,线程共享相同的内存和资源,这使得这种切换类型非常快速且效率更高。只需要保存和恢复特定于线程的数据,例如寄存器和程序计数器。这通常在多线程应用程序中看到,其中各个线程处理各个功能——例如,浏览器可以同时使用一个线程渲染页面和下载内容。由于内存上下文保持不变,线程切换的开销比进程切换低。

3. 中断上下文切换

当 CPU 阻止当前进程或线程执行以处理中断时,会发生中断上下文切换——中断是一个信号,表明某些现象需要立即关注。CPU 会快速保存当前位置,切换到称为中断处理程序的特定例程,并处理事件。中断处理完成后,CPU 会恢复之前的上下文并恢复一般执行。这种切换系统对于实时响应很重要,例如响应键盘输入或嵌入式设备中的硬件信号。

上下文切换的例子

假设多个进程存储在进程控制块(PCB)中。一个进程正在 CPU 上运行以执行其任务。当该进程运行时,另一个具有更高优先级的进程到达就绪队列,需要使用 CPU 完成其任务。在这里,我们使用上下文切换,将当前进程与需要 CPU 完成其任务的新进程进行切换。在切换进程时,上下文切换会将旧进程的状态保存在寄存器中。当进程重新加载到 CPU 时,它将从新进程停止旧进程的地方开始执行。如果我们不保存进程的状态,我们就必须从初始级别开始执行。通过这种方式,上下文切换有助于操作系统在进程之间切换,并在需要执行任务时存储或重新加载进程。

上下文切换的触发因素

以下是上下文切换的三个触发因素:

  1. 中断
  2. 多任务处理
  3. 内核/用户切换

1. 定时器中断(时间片耗尽)

大多数现代操作系统都使用抢占式多任务处理,这意味着它们会强制在进程之间切换,以确保没有单个进程独占 CPU。为此,操作系统会为每个进程设置一个短时间(称为时间片或量子)。当该时间结束后,系统硬件计时器会产生一个定时器中断。这会告诉操作系统该切换了,以阻止当前进程并运行另一个进程。这种上下文切换是最常见的触发因素之一,有助于确保所有正在运行的程序之间的公平性。

2. I/O 阻塞或阻塞系统调用

有时,一个进程在完成输入/输出(I/O)任务(例如从文件读取、打印文档或等待用户按键)之前无法继续。在此期间,如果 CPU 仅仅等待,就会被浪费。相反,操作系统会阻塞该进程并进行上下文切换,允许另一个(已准备好运行的)进程使用 CPU。这通过防止 CPU 在进程等待 I/O 完成时处于空闲状态来提高整体效率。

3. 系统调用和内核事件

当一个进程请求操作系统服务(例如访问或分配内存)时,它会调用一个系统调用。这会导致 CPU 从用户模式切换到内核模式,在那里 OS 可以安全地执行请求。根据情况,OS 可能会决定切换到另一个进程——特别是如果当前进程在等待所请求的操作时被阻塞。因此,系统调用可能会引发上下文切换,无论是出于安全原因还是效率原因。

4. 硬件和软件中断

中断是特殊的信号,用于告知 CPU 某些事情很重要,需要立即关注。例如,当您在键盘上打字或移动鼠标时,会生成一个硬件中断。同样,某些软件条件也可能导致软件中断。当发生中断时,CPU 会停止其当前功能,保存其位置,并切换到称为中断处理程序的特定程序。中断处理完成后,OS 可以返回到之前的任务,或者决定运行一个单独的进程——这将导致上下文切换。

5. 优先级变化

在使用优先级调度系统的系统中,某些进程被认为比其他进程更重要。如果一个高优先级进程在等待就绪,而一个低优先级进程正在运行,OS 可以抢占(中断)低优先级进程,切换到更重要的进程。这种上下文切换确保了重要或时间敏感的功能(如实时应用程序或系统进程)尽快获得 CPU 的关注。

6. 进程完成或终止

当一个进程完成其工作或被终止(由系统或用户)时,CPU 就变得空闲。此时,OS 会进行上下文切换,选择下一个就绪的进程来运行。这确保了当有工作要做时,CPU 永远不会处于不活跃状态。

什么是 PCB?

PCB(进程控制块)是操作系统中使用的数据结构,用于存储与进程相关的所有信息。例如,当在操作系统中创建一个进程时,进程的更新信息、进程的切换信息、终止进程的信息都存储在 PCB 中。

当创建一个进程时,OS 会为其创建一个 PCB。该 PCB 在进程存在期间一直保留在内存中,并在整个进程的生命周期中不断更新。在上下文切换期间,OS 会将一个进程的当前状态保存在其 PCB 中,并从另一个进程的 PCB 中恢复其状态——这使得 CPU 可以轻松地在任务之间切换。

PCB 的主要组成部分

PCB 的内容可能会因操作系统而略有不同,但通常包括以下内容:

1. 进程 ID (PID)

为每个进程分配的唯一标识符。这有助于 OS 区分不同的进程。

2. 进程状态

指示进程的当前状态,例如运行、就绪、阻塞或终止。

3. 程序计数器

指示进程下次被 CPU 重新调度时将要执行的指令。

4. CPU 寄存器

存储进程正在使用的各种 CPU 寄存器的值(例如累加器、堆栈指针等)。这些在上下文切换期间被保存,以便进程稍后可以正确地恢复。

5. 内存管理信息

包括基址和限址寄存器、页表或段表等详细信息——如何管理和访问进程的内存。

6. 记账信息

跟踪进程已使用了多少 CPU 时间、还将使用多少时间以及其他资源使用情况。这有助于调度和资源分配。

7. I/O 状态信息

分配给进程的 I/O 设备列表、已打开的文件以及待处理的 I/O 请求。

上下文切换步骤

进程的上下文切换涉及几个步骤。下图描绘了两个进程 P1 到 P2 的上下文切换,当就绪队列的 PCB 中出现中断、I/O 请求或优先级更高的进程时。

What is the context switching in the operating system

正如我们在图中所见,最初,P1 进程正在 CPU 上运行以执行其任务,同时,另一个进程 P2 处于就绪状态。如果发生错误或中断,或者进程需要输入/输出,P1 进程将其状态从运行状态切换到等待状态。在改变 P1 进程状态之前,上下文切换会将 P1 进程的上下文以寄存器和程序计数器的形式保存到 **PCB1** 中。之后,它将 P2 进程的状态从就绪状态从 **PCB2** 加载到运行状态。

切换进程 P1 到进程 P2 时执行以下步骤:

  1. 首先,上下文切换需要将进程 P1 的状态(以程序计数器和寄存器的形式)保存到处于运行状态的 PCB(进程控制块)中。
  2. 现在更新 P1 进程的 PCB,并将其移动到适当的队列,例如就绪队列、I/O 队列和等待队列。
  3. 之后,另一个进程进入运行状态,或者我们可以从就绪状态选择一个新进程来执行,或者该进程具有更高的优先级来执行其任务。
  4. 现在,我们需要更新所选进程 P2 的 PCB(进程控制块)。这包括将进程状态从就绪状态切换到运行状态,或从阻塞、退出或挂起等其他状态切换。
  5. 如果 CPU 已经执行了进程 P2,我们需要获取进程 P2 的状态,以便在系统中断发生的时间点恢复其执行。

类似地,将进程 P2 从 CPU 中切换出来,以便进程 P1 可以恢复执行。P1 进程从 PCB1 重新加载到运行状态,以便在同一地点恢复其任务。否则,信息将丢失,当进程再次执行时,它将从初始级别开始执行。

上下文切换与调度

上下文切换和 CPU 调度是操作系统中两个紧密相关的概念,它们共同实现了多任务处理和高效的 CPU 利用。虽然它们是不同的过程,但它们相互依赖,并且经常一起出现。

什么是调度?

CPU 调度是操作系统确定哪个进程应该在 CPU 上运行的方法。当有许多进程准备运行时,OS 会使用调度算法(例如先来先服务、轮转、最短作业优先或优先级调度)来选择最合适的进程。

调度确保:

  • CPU 时间在所有进程之间公平共享。
  • 系统响应能力得以维持。
  • 高优先级或时间相关的任务及时获得 CPU 访问权。

调度如何导致上下文切换

每当调度程序选择一个新进程运行时,OS 就需要将 CPU 从当前进程切换到所选进程。这种阻止一个进程并启动另一个进程的任务称为上下文切换。

例如

在轮转调度中,每个进程都有一个短的固定时间片。当时间片结束时,会发生定时器中断,调度程序选择队列中的下一个进程,OS 会进行上下文切换。

在优先级调度中,如果一个高优先级进程进入就绪队列,OS 可以抢占当前进程,从而导致上下文切换以允许高优先级进程运行。

因此,调度决策直接触发上下文切换。

为什么上下文切换对调度很重要

上下文切换是调度程序能够实现多任务处理的关键。没有上下文切换:

  • CPU 无法从一个进程转到另一个进程。
  • 无法应用任何调度算法。
  • 多任务处理和实时处理将不可行。

每次做出调度决策时,OS 都会进行上下文切换,以保存当前进程的状态并加载调度程序选择的下一个进程的状态。

上下文切换的优缺点

上下文切换的优点

1. 实现多任务处理

上下文切换允许多个进程有效地共享 CPU。这实现了多任务处理,可以同时运行多个应用程序,提高系统的响应能力和用户体验。

2. 高效的 CPU 利用

当一个进程正在等待时(例如,等待 I/O),CPU 可以切换到另一个就绪的进程,而不是空闲等待。这确保了 CPU 始终在工作,不会浪费宝贵的时间。

3. 支持公平性和调度

通过上下文切换,操作系统可以应用调度算法(如轮转调度或优先级调度),确保每个进程都能获得适当的 CPU 访问权,并优先处理重要任务。

4. 提高系统响应能力

在实时和交互式系统(如移动设备或用户界面的操作系统)中,上下文切换有助于系统快速响应输入、阻塞和紧急任务。

5. 实现进程隔离

每个进程都有自己独立的上下文,该上下文被独立保存和恢复。这有助于隔离进程,提高系统稳定性和安全性,因为一个进程的故障或不当行为不会影响其他进程。

上下文切换的缺点

1. 性能开销

每次进行上下文切换时,系统都需要花费时间来保存和加载进程的状态。这些切换时间不会对实际性能做出贡献,并导致性能开销。

2. CPU 负载增加

频繁的上下文切换会增加 CPU 的负载,因为它需要更频繁地处理状态。这可能导致性能下降,尤其是在资源有限的系统上。

3. 缓存失效

每个进程都可以使用不同的内存和数据。当上下文切换时,CPU 缓存的内容可能不再相关,需要被替换。这降低了 CPU 缓存的效率,从而减慢了内存访问速度。

4. 设计复杂性

在操作系统中实现上下文切换和调度需要仔细的设计,以避免错误、死锁和禁用。这增加了系统内核和系统资源管理的复杂性。

5. 延迟问题

在上下文切换过多的系统中,每个进程实际运行的时间可能会大大缩短,这可能会导致延迟或滞后——尤其是在实时应用程序中。

常见问题解答

Q1. 什么是操作系统中的上下文切换?

上下文切换是 CPU 停止执行一个进程并开始执行另一个进程的过程。操作系统会保存当前进程的状态(上下文),并加载保存的状态,以便它可以从中断处继续。

Q2. 为什么需要上下文切换?

上下文切换对于多任务处理是必需的。它允许 CPU 在多个进程之间切换,从而使系统更高效、响应更快,并能够同时处理许多任务。

Q3. 在上下文切换期间保存了哪些信息?

操作系统会保存进程的 CPU 寄存器、程序计数器、堆栈指针和其他相关的进程控制块(PCB)中的数据。这些信息在进程恢复时会被恢复。