当前位置: 首页 > news >正文

Linux 性能实战 | 第 8 篇 上下文切换、内核线程与调度延迟

Linux 性能实战 | 第 8 篇 上下文切换、内核线程与调度延迟 🐢

🔗 上下文切换:CPU 的“换挡”开销

在上一章中,我们探讨了调度器如何通过进程迁移来实现 CPU 负载均衡。我们提到了迁移是有成本的,这个成本的核心就是上下文切换 (Context Switch)

想象一下你正在专注地写一份复杂的代码(执行一个进程),这时突然来了一个紧急电话(中断),你不得不放下手头的工作,记录下当前的思路(保存现场),然后去处理电话(切换到内核态处理中断)。打完电话后,你还需要回忆刚才写到哪里了(恢复现场),才能继续编程。这个“放下-切换-恢复”的过程,就是一次上下文切换。

对 CPU 而言,上下文切换意味着:

  1. 保存当前进程/线程的“快照”:包括 CPU 寄存器(程序计数器、栈指针等)、进程状态、内存管理信息等。
  2. 加载下一个进程/线程的“快照”到 CPU 寄存器中。
  3. 刷新 TLB (Translation Lookaside Buffer):导致虚拟地址到物理地址的缓存失效。
  4. CPU 缓存失效:新进程的代码和数据很可能不在 CPU 的 L1/L2/L3 缓存中,需要从更慢的内存中重新加载。

一句话总结:上下文切换是必要的“恶”。没有它,多任务系统无法工作。但过于频繁的切换,就像一个员工不停地在多个任务间来回切换,大部分时间都浪费在了“切换”本身,而不是真正地“执行”任务,导致系统整体效率大幅下降。


🤔 什么时候会发生上下文切换?

上下文切换主要分为三类:

1. 进程上下文切换 (Process Context Switch)

这是开销最大的一种切换。它不仅涉及到内核态和用户态的切换,还涉及到虚拟内存空间的切换。

  • 时间片用完:CFS 调度器为了“公平”,会中断当前进程,让给vruntime更小的进程。
  • 进程阻塞:当进程需要等待某个资源时,如等待磁盘 I/O、等待网络数据、或者通过sleep主动挂起,它会被置为INTERRUPTIBLEUNINTERRUPTIBLE状态,从而触发调度,让出 CPU。
  • 更高优先级的进程就绪:一个实时进程(如SCHED_RR)变为可运行状态,会立即抢占当前正在运行的普通进程。

2. 线程上下文切换 (Thread Context Switch)

当同一进程内的两个线程之间发生切换时,因为它们共享同一个虚拟内存空间,所以切换时不需要更换页表,TLB 也不会被完全刷新。因此,它的开销比进程上下文切换要小得多。

3. 中断上下文切换 (Interrupt Context Switch)

为了快速响应硬件事件(如网卡收到数据包、硬盘完成读写),CPU 会暂停当前运行的进程,切换到内核态去执行一个中断服务程序 (Interrupt Service Routine, ISR)

中断上下文的切换非常快,因为它只涉及少量内核信息的保存和恢复,不涉及用户进程。但它会打断正常进程的执行,如果中断过于频繁,也会严重影响系统性能。


🛠️ 实战:定位上下文切换元凶

场景:一个高并发的 Web 服务器,在压力测试期间,top显示系统 CPU 使用率并不高(例如,us+sy只有 30%),但load average却异常地高,并且服务响应延迟(RT)剧增。

1. 初步诊断:vmstat

vmstat是快速发现上下文切换问题的利器。

# 每秒输出一次报告vmstat1

输出

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 123456 10240 567890 0 0 0 20 1024 200000 15 15 70 0 0 2 0 0 123450 10240 567892 0 0 0 30 1280 250000 18 17 65 0 0 1 0 0 123440 10240 567898 0 0 0 25 1150 220000 16 16 68 0 0

关注两列:

  • cs(context switch):每秒上下文切换的次数。这个值通常在几千到几万是正常的。但如果飙升到几十万甚至上百万,就表明系统存在严重的调度问题。
  • in(interrupt):每秒中断的次数。

在这个案例中,cs高达 20 多万,显然是问题的根源。CPU 的大部分时间都花在了“换挡”上,而不是在执行应用代码(us)或内核代码(sy)。

2. 深入分析:pidstat

找到了问题,下一步就是定位是哪个进程导致的。pidstatsysstat工具包中的一员,专门用于分析进程级别的统计信息。

# -w: 显示上下文切换信息# -p ALL: 监控所有进程# 1: 每秒输出一次pidstat -w -p ALL1

输出

Linux 5.4.0-100-generic (hostname) 01/31/26 _x86_64_ (8 CPU) 10:30:01 UID PID cswch/s nvcswch/s Command 10:30:02 1000 12345 150000.00 5.00 nginx 10:30:02 0 54321 200.00 10.00 kworker/u16:0 10:30:02 1001 9876 10.00 0.00 redis-server ...

关注两列:

  • cswch/s(voluntary context switches)自愿上下文切换。通常是因为进程等待资源(如 I/O)而主动放弃 CPU。如果这个值很高,说明应用可能存在大量的 I/O 等待或者同步锁竞争。
  • nvcswch/s(non-voluntary context switches)非自愿上下文切换。通常是因为时间片用完,或者被更高优先级的进程抢占。如果这个值很高,说明 CPU 正在被多个活跃进程激烈争抢。

pidstat的输出中,我们一目了然地看到nginx进程(PID 12345)每秒产生了 15 万次自愿上下文切换。这说明nginx的 worker 进程在疯狂地等待某个资源,导致它们不断地被挂起和唤醒。

可能的原因

  • 后端服务瓶颈nginx作为反向代理,后端应用(如 PHP、Java)处理缓慢,导致nginxworker 大量阻塞在网络 I/O 上。
  • 锁竞争:应用代码中存在设计不当的全局锁,导致大量线程在等待同一个锁。
  • 连接数过多nginx配置的worker_connections过高,而系统资源(如文件描述符)不足。

通过这个线索,开发和运维团队就可以进一步深入到nginx的配置和后端应用代码中,找到最终的性能瓶颈。


👽 神秘的内核线程:kworkerksoftirqd

在使用topps时,你经常会看到一些以k开头的、方括号括起来的进程,如kworkerksoftirqd。它们是内核线程 (Kernel Threads),在后台为操作系统执行各种管理任务。

kworker:内核的“临时工”

kworker是内核工作队列(workqueue)的执行者。内核的各个子系统(如磁盘、网络、定时器)会把一些耗时较长、不能在中断上下文中完成的任务,打包成一个“工作项”,扔到工作队列里,然后由kworker线程在未来的某个时刻异步地去执行。

命名格式kworker/u<cpu_id>:<worker_id>kworker/<cpu_id>:<worker_id>

  • u表示这个kworker是非绑定的(unbound),可以在多个 CPU 核心间迁移。
  • <cpu_id>表示它主要在哪个 CPU 上活动。

如果kworker的 CPU 使用率很高,通常意味着内核正在忙于处理某些后台任务。你可以通过perf工具来追踪kworker到底在忙什么。

ksoftirqd:软中断的“清道夫”

当硬件中断(硬中断)发生得过于频繁时,为了避免长时间关中断影响系统响应,内核会将一部分耗时较长的处理工作推迟,变成软中断 (softirq)

ksoftirqd就是专门用来处理软中断的内核线程,每个 CPU 核心都有一个。如果软中断的产生速度超过了处理速度,积压的软中断就会由ksoftirqd来“兜底”处理。

命名格式ksoftirqd/<cpu_id>

如果你在top中看到si(softirq)或者ksoftirqd的 CPU 使用率很高,通常指向以下问题:

  • 网络风暴:网络收发包极其频繁,导致大量的网络软中断。
  • 内核锁竞争:内核中处理软中断的逻辑遇到了锁竞争,导致处理效率下降。

📝 总结与展望

  • 上下文切换是核心成本:过高的cs值是系统“内耗”的明确信号。使用vmstat发现问题,再用pidstat -w定位到具体进程。
  • 区分自愿与非自愿切换cswch/s高通常指向 I/O 或锁等待问题;nvcswch/s高通常指向 CPU 资源不足或争抢激烈。
  • 关注内核线程kworkerksoftirqd的高 CPU 占用率是内核层面存在瓶颈的线索,通常与 I/O 和网络活动密切相关。

下一篇预告

在本章中,我们学会了如何量化和定位上下文切换带来的性能损耗。我们不仅掌握了vmstatpidstat这两个强大的诊断工具,还认识了kworkerksoftirqd这两个重要的内核“打工人”。

在下一章,我们将继续深入 CPU 的世界,专门探讨软中断和硬中断。我们将揭示top命令中hisi的真正含义,并学习如何处理由它们引发的性能问题。敬请期待!

http://www.jsqmd.com/news/356058/

相关文章:

  • 大模型学习必备:14个核心概念详解,建议收藏反复阅读
  • CF1511G
  • 程序员必看:如何像带新员工一样“训练“你的AI智能体
  • 降AI率神器怎么选?十大降AI工具避坑指南!我肝了三天实测,吐血整理这份毕业保命清单(含免费版)
  • PiliPlus 1.1.6 | 基于Flutter开发的第三方哔哩,目前最好用的一款
  • COTX茶月山无门槛红包怎么领?美团“集金卡”活动,让你春节喝茶更划算! - Top品牌推荐
  • 论文AI率高怎么办?降AI率神器怎么选?我肝了三天实测这10款降AI工具,吐血整理这份毕业保命清单
  • COTX茶月山怎么点更便宜?美团让你轻松省钱! - Top品牌推荐
  • 【YOLOv10多模态创新改进】独家特征融合创新篇 | ICCV 2025 | 引入 FDAM 特征差异对齐模块,适合可见光与红外图像融合目标检测、多模态图像融合目标检测、多模态遥感图像分割有效涨点
  • 薅羊毛指南:Costa Coffee 美团平台超值攻略,让你喝出品质与实惠! - Top品牌推荐
  • TCN-Transformer-BiGRU组合模型回归+SHAP分析+新数据预测+多输出!深度学习可解释分析
  • agentscope 调用vlm
  • 【YOLOv12多模态创新改进】独家特征融合创新篇 | ICCV 2025 | 引入 FDAM 特征差异对齐模块,适合可见光与红外图像融合目标检测、多模态图像融合目标检测、多模态遥感图像分割有效涨点
  • PHP Error: 常见错误及其解决方法
  • 【蓝桥杯】一些有意思的题
  • 2026年2月螺杆挤压制粒机厂家选择指南,硬料造粒场景与设备规格选择 - 品牌鉴赏师
  • 完整教程:【SpringAI】10.结构化输出
  • COTX茶月山外卖配送费怎么减?美团“半价周末”及新春神券,让你省到就是赚到! - Top品牌推荐
  • 这5个“计算机专业”就业很吃香,毕业生需求量大,还不会过时_计算机最好的5个专业
  • AI如何根据Mermaid文字格式,从而绘制精美准确的图像?
  • 2026年2月小型实验用流化造粒床公司推荐,专业造粒制造与品牌保障口碑之选 - 品牌鉴赏师
  • 2026年2月实验室小型真空干燥设备公司推荐,烘干设备制造品牌保障 - 品牌鉴赏师
  • Costa Coffee咖啡无门槛红包,美团让你畅享钜惠! - Top品牌推荐
  • Linux 脚本案例:适用iptables构建不同场景下的防火墙规则
  • 系统思考:业务创新与组织重构
  • 【小程序毕设源码分享】基于springboot+小程序的共享雨伞租赁系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • Costa Coffee 咖啡点单攻略:美团优惠,6.9元起,省钱秘籍大公开! - Top品牌推荐
  • wifi密码pj工具(Aircrack-ng/​WiFiCrackTool​)
  • 700cc 的省钱秘籍:美团,你的省钱“饮”力者! - Top品牌推荐
  • wsl中改了 /etc/resolv.conf,一重启就没了?