1. 实时系统基础:实时内核与普通内核的区别、PREEMPT_RT 补丁的演进历史、硬实时与软实时的概念
1.1 实时内核与普通内核的核心区别
普通 Linux 内核(如主线内核)的设计目标是最大化系统吞吐量和公平性,而实时内核(如 PREEMPT_RT)追求的是可预测的低延迟。两者的根本差异在于对临界区和中断处理的抢占行为。
关键认知: 普通内核中,一个低优先级任务持有自旋锁时,高优先级任务只能等待,导致优先级反转。PREEMPT_RT 通过将自旋锁替换为可抢占的互斥锁(rt_mutex),并启用优先级继承,从根本上消除了不可预测的延迟。
| 对比维度 | 普通内核 (主线) | 实时内核 (PREEMPT_RT) |
|---|---|---|
| 抢占模型 | PREEMPT_NONE / PREEMPT_VOLUNTARY | PREEMPT_FULL (强制完全抢占) |
| 中断处理 | 中断上下文不可被任务抢占 | 中断线程化,可被高优先级实时任务抢占 |
| 自旋锁 | 原子操作,禁止抢占 | 替换为 rt_mutex,支持睡眠和优先级继承 |
| RCU 读侧 | 可能禁止抢占 | 可抢占 RCU (PREEMPT_RCU) |
| 时钟精度 | HZ=100/250/1000,高精度定时器可选 | 强制高精度定时器 (HRTIMER),支持微秒级唤醒 |
| 最坏情况延迟 | 毫秒级甚至百毫秒级 | 微秒级(通常 < 100μs) |
实战提示: 在排查延迟抖动时,首先确认内核是否启用了
CONFIG_PREEMPT_RT=y。可以通过 uname -a 查看内核版本是否包含 -rt 标识,或检查 /proc/sys/kernel/sched_rt_runtime_us 是否存在。
1.2 PREEMPT_RT 补丁的演进历史
PREEMPT_RT 补丁集由 Thomas Gleixner 等人维护,经历了近 20 年的演进,最终在 2024 年合入 Linux 6.12 主线。其演进过程反映了实时 Linux 从“实验性”到“工业级”的蜕变。
版本陷阱: 即使内核版本高于 6.12,如果发行版未开启
CONFIG_PREEMPT_RT,系统仍然不是实时内核。务必通过 zcat /proc/config.gz | grep PREEMPT_RT 确认配置。
1.3 硬实时与软实时的概念
实时系统根据对截止时间(Deadline)的违反容忍度,分为硬实时和软实时。PREEMPT_RT 通常被归类为软实时系统,但在精心配置下可以逼近硬实时要求。
- 硬实时(Hard Real-Time): 错过截止时间会导致灾难性后果(如飞行控制、心脏起搏器)。系统必须保证在最坏情况下的响应时间。
- 软实时(Soft Real-Time): 偶尔错过截止时间会降低服务质量,但不会造成灾难(如音频/视频播放、工业数据采集)。系统追求的是统计意义上的低延迟。
- 固实时(Firm Real-Time): 介于两者之间,错过截止时间会导致结果无效,但系统可以继续运行(如实时视频帧处理)。
| 特性 | 硬实时 | 软实时 (PREEMPT_RT 典型场景) |
|---|---|---|
| 截止时间违反后果 | 系统失效 / 安全风险 | 性能下降 / 数据丢帧 |
| 延迟保证 | 确定性(最坏情况已知) | 概率性(99.9% 在阈值内) |
| 典型应用 | 航空电子、医疗设备、汽车引擎控制 | 音频处理、机器人控制、工业 PLC |
| Linux 适用性 | 需配合专用硬件(如 RTOS + FPGA) | PREEMPT_RT 即可满足 |
| 抖动容忍度 | 零容忍 | 容忍微秒级抖动 |
延迟抖动(Jitter)定义: 实际响应时间与期望响应时间之间的偏差。在 PREEMPT_RT 系统中,抖动通常由中断延迟、调度延迟、锁竞争和缓存未命中引起。本课程后续章节将围绕这些抖动源展开排查。
1.4 实时系统的延迟构成
理解延迟的构成是排查抖动的前提。一个实时任务的完整响应延迟可以分解为以下阶段:
排查起点: 使用
cyclictest 工具测量系统的最小/最大/平均延迟。如果最大延迟超过 100μs,说明系统存在明显的抖动源,需要进入后续章节的专项排查流程。
1.5 本章小结
- PREEMPT_RT 通过中断线程化、自旋锁替换和完全抢占三大机制,将 Linux 从“吞吐优先”转变为“延迟可预测”。
- 补丁演进从 2005 年的实验性补丁到 2024 年合入主线,标志着 Linux 实时能力的成熟。
- 硬实时要求确定性保证,软实时(PREEMPT_RT 的典型场景)容忍统计意义上的微秒级抖动。
- 延迟由中断、调度、抢占、执行四个阶段构成,每个阶段都可能引入抖动,需要针对性排查。