进程的上下文切换

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、进程的组成部分

进程由进程控制块PCB(process control block)和程序组成。

  • 进程控制块
    • 建立进程会创建一个PCB
    • 回收进程会撤销对应的PCB
  • 程序又由代码、数据、堆和栈组成。
    • 栈:保存返回点、参数、返回值、局部变量
    • 堆:动态变量

二、进程上下文的组成部分

进程的物理实体(代码和数据等)和支持进程运行的环境合称为进程的上下文

  • 由进程的程序块、数据块、运行时的堆和用户栈(两者通称为用户堆栈)等组成的用户空间信息被称为用户级上下文
  • 由进程标识信息、进程现场信息、进程控制信息和系统内核栈等组成的内核空间信息被称为系统级上下文。
  • 处理器中各寄存器的内容被称为寄存器上下文(也称硬件上下文),即进程的现场信息。

三、何时发生上下文切换

下降进程自身造成切换(例如产生异常)或者外界强制下降进程和上升进程切换(例如cpu时间片用完)。
下降进程指的是当前即将被中断运行的进程。
上升进程指的是按照调度算法从就绪队列中选择的一个即将被运行的进程。

四、进程上下文切换具体流程

(1)保存当前进程的硬件上下文(PC/PSW/SP和通用寄存器等);

  • 对linux系统而言,其硬件上下文大部分保存在struct thread_struct thread中,但通用寄存器(eax/ebx等保存在内核栈里)

(2)修改当前进程的PCB,比如将其状态由运行改为就绪或者阻塞,并将该进程PCB加入相关队列;
(3)调度另外一个进程(这涉及调度)
(4)修改被调度进程的PCB,将其状态改为运行(系统上下文)
(5)将“当前进程”的存储管理数据改为被调度进程的存储管理信息(如页表、TLB)(用户级上下文)
(6)恢复新进程的硬件上下文(即现场),让PC指向新进程代码

进程上下文切换操作系统实现多任务并发执行的核心机制之一。其核心原理是当处理器从一个进程切换到另一个进程时,保存当前进程的状态,并恢复下一个进程的状态,从而保证多个进程可以交替执行。在Linux内核中,这一过程由内核调度器管理,并分为两个主要阶段:**地址空间切换**和**处理器状态切换(硬件上下文切换)**。 地址空间切换主要负责更新处理器的内存管理单元(MMU),确保即将执行的进程能够访问到自己的指令和数据[^2]。Linux中通过页表机制实现进程的虚拟地址空间隔离,每次切换时,内核会更新页表基址寄存器(如x86架构的CR3寄存器)指向新进程的页表。为了提高性能,现代处理器还引入了ASID(Address Space Identifier)机制,允许TLB(Translation Lookaside Buffer)缓存不同进程的地址转换信息,避免每次上下文切换时都清空TLB,从而减少地址转换的开销。 处理器状态切换则涉及寄存器状态的保存与恢复。包括通用寄存器、程序计数器(PC)、栈指针(SP)等关键寄存器的内容。在Linux中,上下文切换的具体实现主要集中在`switch_to`宏中,该宏定义在`include/asm-generic/system.h`或架构相关的头文件中(如x86中的`include/asm-x86/system.h`)[^1]。在调度器决定切换进程后,`switch_to`会将当前进程的寄存器状态保存到其内核栈中,并从目标进程的内核栈中恢复寄存器状态,从而完成执行流的切换上下文切换是一个代价较高的操作,因为它涉及寄存器的保存和恢复、TLB刷新、缓存失效等操作。频繁的上下文切换会导致CPU缓存命中率下降,影响系统性能。因此,在高并发系统中,合理设计调度策略以减少不必要的上下文切换是提升性能的重要手段之一[^3]。 可以通过`vmstat`和`pidstat`等工具监控系统的上下文切换情况。例如,使用`pidstat -w`命令可以查看每个进程上下文切换频率,帮助分析系统性能瓶颈[^4]。 ### 上下文切换的代码示例 以下是一个简化的上下文切换伪代码示例,展示了保存和恢复寄存器的基本流程: ```c struct thread_struct { unsigned long rsp0; // 内核栈指针 unsigned long rip; // 程序计数器 unsigned long rsp; // 用户栈指针 // 其他寄存器保存字段... }; void switch_to(struct task_struct *prev, struct task_struct *next) { // 保存当前进程的寄存器状态到prev的thread_struct中 save_state(&prev->thread); // 从next的thread_struct中恢复寄存器状态 restore_state(&next->thread); } ``` 上述代码仅为示意,实际的实现涉及更复杂的细节,例如调度器的调用路径、中断屏蔽、原子性保障等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值