高 进阶
上下文切换开销#
一句话答案#
上下文切换保存/恢复 CPU 寄存器,进程切换还需切换页表导致 TLB 失效;线程切换比进程快,协程比线程更快。
核心要点
开销来源:
- 保存/恢复 CPU 寄存器
- 进程切换:页表切换 + TLB 全失效
- Cache 冷启动
量级: 进程切换 ~数十微秒,线程切换 ~数微秒
减少: 协程(用户态调度) / 线程池(复用线程) / IO多路复用(减少线程数)
面试回答(2分钟版)
上下文切换是操作系统在不同执行单元之间切换时保存和恢复 CPU 状态的过程。切换时需要保存当前执行单元的寄存器值、程序计数器、栈指针等到内存中的 PCB 或 TCB,然后加载目标执行单元之前保存的状态。进程切换的开销最大,除了寄存器保存恢复外还需要切换页表,页表切换会导致 TLB 缓存全部失效,后续的内存访问都要重新做地址翻译,再加上 CPU Cache 冷启动,一次进程切换大约需要数十微秒。线程切换的开销小得多,因为同一进程内的线程共享地址空间不需要切换页表,只需要保存恢复线程私有的寄存器和栈,大约数微秒。协程切换开销最小,它完全在用户态完成不需要陷入内核,几百纳秒级别。在实际工程中减少上下文切换的常见手段有:使用线程池复用线程避免频繁创建销毁、使用 IO 多路复用减少线程数量、使用协程替代线程、使用无锁数据结构减少锁竞争导致的阻塞切换。可以通过 vmstat 命令的 cs 列监控系统的上下文切换次数。
追问与易错
追问方向:
- “怎么减少上下文切换?”→ 线程池复用线程、IO 多路复用减少线程数、协程替代线程(用户态切换)、无锁数据结构(CAS)减少阻塞切换、CPU 亲和性绑定
- “怎么监控切换次数?”→
vmstat的 cs 列看系统级切换、pidstat -w看进程级切换、/proc/PID/status的 voluntary/nonvoluntary_ctxt_switches - “自愿和非自愿切换区别?”→ 自愿切换是进程主动让出 CPU(如 IO 等待、sleep),非自愿切换是被调度器强制抢占(时间片用完、高优先级抢占)
易错点:
- ❌ 上下文切换开销可忽略——高频时显著影响性能
- ❌ 混淆进程和线程切换开销