Linux 性能实战 | 第 8 篇 上下文切换、内核线程与调度延迟
Linux 性能实战 | 第 8 篇 上下文切换、内核线程与调度延迟 上下文切换CPU 的“换挡”开销在上一章中我们探讨了调度器如何通过进程迁移来实现 CPU 负载均衡。我们提到了迁移是有成本的这个成本的核心就是上下文切换 (Context Switch)。想象一下你正在专注地写一份复杂的代码执行一个进程这时突然来了一个紧急电话中断你不得不放下手头的工作记录下当前的思路保存现场然后去处理电话切换到内核态处理中断。打完电话后你还需要回忆刚才写到哪里了恢复现场才能继续编程。这个“放下-切换-恢复”的过程就是一次上下文切换。对 CPU 而言上下文切换意味着保存当前进程/线程的“快照”包括 CPU 寄存器程序计数器、栈指针等、进程状态、内存管理信息等。加载下一个进程/线程的“快照”到 CPU 寄存器中。刷新 TLB (Translation Lookaside Buffer)导致虚拟地址到物理地址的缓存失效。CPU 缓存失效新进程的代码和数据很可能不在 CPU 的 L1/L2/L3 缓存中需要从更慢的内存中重新加载。一句话总结上下文切换是必要的“恶”。没有它多任务系统无法工作。但过于频繁的切换就像一个员工不停地在多个任务间来回切换大部分时间都浪费在了“切换”本身而不是真正地“执行”任务导致系统整体效率大幅下降。 什么时候会发生上下文切换上下文切换主要分为三类1. 进程上下文切换 (Process Context Switch)这是开销最大的一种切换。它不仅涉及到内核态和用户态的切换还涉及到虚拟内存空间的切换。时间片用完CFS 调度器为了“公平”会中断当前进程让给vruntime更小的进程。进程阻塞当进程需要等待某个资源时如等待磁盘 I/O、等待网络数据、或者通过sleep主动挂起它会被置为INTERRUPTIBLE或UNINTERRUPTIBLE状态从而触发调度让出 CPU。更高优先级的进程就绪一个实时进程如SCHED_RR变为可运行状态会立即抢占当前正在运行的普通进程。2. 线程上下文切换 (Thread Context Switch)当同一进程内的两个线程之间发生切换时因为它们共享同一个虚拟内存空间所以切换时不需要更换页表TLB 也不会被完全刷新。因此它的开销比进程上下文切换要小得多。3. 中断上下文切换 (Interrupt Context Switch)为了快速响应硬件事件如网卡收到数据包、硬盘完成读写CPU 会暂停当前运行的进程切换到内核态去执行一个中断服务程序 (Interrupt Service Routine, ISR)。中断上下文的切换非常快因为它只涉及少量内核信息的保存和恢复不涉及用户进程。但它会打断正常进程的执行如果中断过于频繁也会严重影响系统性能。️ 实战定位上下文切换元凶场景一个高并发的 Web 服务器在压力测试期间top显示系统 CPU 使用率并不高例如ussy只有 30%但load average却异常地高并且服务响应延迟RT剧增。1. 初步诊断vmstatvmstat是快速发现上下文切换问题的利器。# 每秒输出一次报告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找到了问题下一步就是定位是哪个进程导致的。pidstat是sysstat工具包中的一员专门用于分析进程级别的统计信息。# -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的配置和后端应用代码中找到最终的性能瓶颈。 神秘的内核线程kworker与ksoftirqd在使用top或ps时你经常会看到一些以k开头的、方括号括起来的进程如kworker和ksoftirqd。它们是内核线程 (Kernel Threads)在后台为操作系统执行各种管理任务。kworker内核的“临时工”kworker是内核工作队列workqueue的执行者。内核的各个子系统如磁盘、网络、定时器会把一些耗时较长、不能在中断上下文中完成的任务打包成一个“工作项”扔到工作队列里然后由kworker线程在未来的某个时刻异步地去执行。命名格式kworker/ucpu_id:worker_id或kworker/cpu_id:worker_idu表示这个kworker是非绑定的unbound可以在多个 CPU 核心间迁移。cpu_id表示它主要在哪个 CPU 上活动。如果kworker的 CPU 使用率很高通常意味着内核正在忙于处理某些后台任务。你可以通过perf工具来追踪kworker到底在忙什么。ksoftirqd软中断的“清道夫”当硬件中断硬中断发生得过于频繁时为了避免长时间关中断影响系统响应内核会将一部分耗时较长的处理工作推迟变成软中断 (softirq)。ksoftirqd就是专门用来处理软中断的内核线程每个 CPU 核心都有一个。如果软中断的产生速度超过了处理速度积压的软中断就会由ksoftirqd来“兜底”处理。命名格式ksoftirqd/cpu_id如果你在top中看到sisoftirq或者ksoftirqd的 CPU 使用率很高通常指向以下问题网络风暴网络收发包极其频繁导致大量的网络软中断。内核锁竞争内核中处理软中断的逻辑遇到了锁竞争导致处理效率下降。 总结与展望上下文切换是核心成本过高的cs值是系统“内耗”的明确信号。使用vmstat发现问题再用pidstat -w定位到具体进程。区分自愿与非自愿切换cswch/s高通常指向 I/O 或锁等待问题nvcswch/s高通常指向 CPU 资源不足或争抢激烈。关注内核线程kworker和ksoftirqd的高 CPU 占用率是内核层面存在瓶颈的线索通常与 I/O 和网络活动密切相关。下一篇预告在本章中我们学会了如何量化和定位上下文切换带来的性能损耗。我们不仅掌握了vmstat和pidstat这两个强大的诊断工具还认识了kworker和ksoftirqd这两个重要的内核“打工人”。在下一章我们将继续深入 CPU 的世界专门探讨软中断和硬中断。我们将揭示top命令中hi和si的真正含义并学习如何处理由它们引发的性能问题。敬请期待

相关新闻

HBase与Kafka集成:构建实时大数据处理管道

HBase与Kafka集成:构建实时大数据处理管道

HBase与Kafka集成:构建实时大数据处理管道 关键词:HBase,Kafka,实时大数据处理,数据集成,处理管道 摘要:本文深入探讨了HBase与Kafka集成以构建实时大数据处理管道的相关技术。首先介绍了HBase和…

2026/7/6 8:53:08 阅读更多 →
wifi密码pj工具(Aircrack-ng/​WiFiCrackTool​)

wifi密码pj工具(Aircrack-ng/​WiFiCrackTool​)

总结: Aircrack-ng更快更专业。一秒上千条以上。 WiFiCrackTool字典破解,一秒一条,特别慢。 Aircrack-ng 的“破解时间”不是一个固定值,而是由以下四件事决定的: 你拿到的是什么攻击入口 密码空间有多大 算力有多…

2026/7/6 13:13:19 阅读更多 →
PHP Error: 常见错误及其解决方法

PHP Error: 常见错误及其解决方法

PHP Error: 常见错误及其解决方法 引言 PHP作为一种广泛使用的服务器端脚本语言,在网站开发中扮演着重要的角色。然而,在使用PHP进行编程时,难免会遇到各种错误。本文将详细介绍PHP中常见的错误类型及其解决方法,帮助开发者更好地应对这些问题。 常见PHP错误类型 1.语法…

2026/7/5 1:55:05 阅读更多 →

最新新闻

西门子PLC程序模板:气缸功能块 FB_AirCylinder 实战拆解

西门子PLC程序模板:气缸功能块 FB_AirCylinder 实战拆解

西门子PLC程序模板:气缸功能块 FB_AirCylinder 实战拆解邓工 2026-07-04 #西门子PLC #S7-1500 #FB_AirCylinder #气缸功能块 #TIA Portal所有气缸统一调用 FB_AirCylinder(FB6020,归属 03Valve 功能段)。标准化封装优点&#xf…

2026/7/6 13:14:00 阅读更多 →
GoogLeNet 与 VGG-16 对比:参数量减少 12 倍背后的 Inception 模块效率分析

GoogLeNet 与 VGG-16 对比:参数量减少 12 倍背后的 Inception 模块效率分析

GoogLeNet 与 VGG-16 深度对比:Inception 模块如何实现 12 倍参数压缩当我们在资源受限的环境中部署深度神经网络时,模型效率往往成为关键考量。2014年ImageNet竞赛中,GoogLeNet以仅700万参数量实现Top-5错误率6.7%,而同期VGG-16的…

2026/7/6 13:14:00 阅读更多 →
Java计算机毕设之基于前后端分离的病毒靶点药物关系数据采集系统的设计与实现 基于 SpringBoot 的生物医药多源数据采集与归档系统(完整前后端代码+说明文档+LW,调试定制等)

Java计算机毕设之基于前后端分离的病毒靶点药物关系数据采集系统的设计与实现 基于 SpringBoot 的生物医药多源数据采集与归档系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/6 13:11:59 阅读更多 →
ICM-42688-P与PIC24HJ256GP610在运动控制中的高效协同

ICM-42688-P与PIC24HJ256GP610在运动控制中的高效协同

1. ICM-42688-P与PIC24HJ256GP610的黄金组合解析在工业自动化和机器人控制领域,传感器与微控制器的协同工作能力直接决定了系统性能的上限。ICM-42688-P作为TDK InvenSense推出的6轴MEMS运动传感器,与Microchip的PIC24HJ256GP610微控制器形成的技术组合&…

2026/7/6 13:07:53 阅读更多 →
STM32与TPAFE0808实现多通道信号采集方案解析

STM32与TPAFE0808实现多通道信号采集方案解析

1. 项目背景与核心需求在工业自动化、医疗设备和精密仪器领域,多通道信号采集与系统监测一直是关键的技术挑战。传统方案往往需要复杂的模拟前端电路和多个分立元件,不仅增加了系统复杂度,还容易引入噪声和漂移问题。TPAFE0808这款8通道可编程…

2026/7/6 13:07:53 阅读更多 →
Unity MyFramework:框架里的代码简化技巧(三)

Unity MyFramework:框架里的代码简化技巧(三)

前两篇写了 MyFramework 里一些常用的代码简化技巧。 这一篇继续写第三组。 不过这次只写真正能让调用侧代码变短的东西。 也就是一眼能看到: 原本要写几行,现在一行就能表达清楚。 这类工具不是复杂系统。 它们更多是项目长期开发中沉淀出来的小函…

2026/7/6 13:03:49 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻