一个高优先级线程被唤醒后,可能还要等关抢占区、硬中断或自旋锁结束。音频、运动控制和工业通信这类周期任务不能只看平均延迟,更要看最长会等多久。PREEMPT_RT 会把许多较长的不可抢占路径缩短,让高优先级线程更早拿到 CPU。
PREEMPT_RT 实际改变了什么
它不是给应用程序加一个“实时开关”,而是重塑了内核中的若干执行上下文。大量原本会忙等的自旋锁,在能够睡眠的情形下会以 rtmutex 方式工作;当高优先级线程等待锁时,持锁者可以得到优先级继承。许多设备中断也会由可调度的 IRQ 线程完成后半段处理,使调度器可以决定它与实时任务谁先运行。
这里的“尽可能”要记住。raw_spinlock、部分底层时钟路径、NMI/SMI 和设备固件仍可能挡住 CPU;驱动关中断太久或固件接管 CPU 时,实时补丁也帮不上忙。装了 PREEMPT_RT 后还要测,不能直接把它当成实时保证。
怎样判断系统是否真的跑在 RT 内核上
首先确认构建配置中启用了 CONFIG_PREEMPT_RT,并在目标机上记录内核版本、启动参数、CPU 型号和 BIOS 版本。某些内核会在 /sys/kernel/realtime 暴露状态;无论是否有该文件,都应以实际的内核配置和延迟测试为准。
1 | uname -a |
接着用 cyclictest 或 rtla timerlat 建立基线,并在相同硬件上比较普通内核与 RT 内核的最大值、P99 和长时间直方图。只在空闲桌面上跑几秒得到的漂亮数字,不是实时能力的证据。
适合它的工作,也有不适合它的工作
PREEMPT_RT 很适合降低通用 Linux 上线程唤醒、锁竞争和中断处理带来的抖动。它不替代硬实时 MCU,不自动让垃圾回收、文件系统写入或网络对端变成确定性,也不保证每个驱动都已经适配得足够好。若控制周期只有几十微秒,或失控会立刻造成物理伤害,应仍由独立控制器与硬件安全链承担最后责任。
部署顺序可以很朴素:先定义周期、截止期和最大允许抖动;再启用 RT 内核;随后布置调度、CPU/IRQ、内存和电源策略;最后在 CPU、内存、网络和 I/O 压力同时存在时捕获尖峰。每削掉一个尖峰,都要能解释它原先来自哪里。