土法炼钢兴趣小组的算法知识备份

【操作系统百科】优先级反转与继承

文章导航

分类入口
os
标签入口
#priority-inversion#priority-inheritance#rt-mutex#preempt-rt#mars-pathfinder

目录

1997 年,火星探路者号(Mars Pathfinder)反复重启——原因是优先级反转。一个低优先级任务持有锁,阻塞了高优先级任务,而中优先级任务抢占了低优先级任务 → 死局。

一、先看图

sequenceDiagram
    participant H as 高优先级<br/>气象任务
    participant M as 中优先级<br/>通信任务
    participant L as 低优先级<br/>数据收集

    L->>L: 获取 mutex
    H->>H: 需要 mutex → 阻塞
    M->>M: 抢占 L(优先级更高)
    M->>M: 长时间运行
    Note over H: H 被 M 间接阻塞<br/>(优先级反转)
    Note over L: L 无法运行<br/>无法释放锁

二、优先级反转

2.1 定义

高优先级任务被低优先级任务间接阻塞,因为中优先级任务抢占了持锁的低优先级任务。

2.2 Mars Pathfinder

低持锁 → 高等锁 → 中抢占低 → 高超时 → watchdog 重启。

修复:VxWorks 开启优先级继承

三、PIP(Priority Inheritance Protocol)

低优先级持锁 → 高优先级等待锁
→ 低优先级临时提升到高优先级
→ 低不会被中抢占
→ 低释放锁 → 恢复原优先级

3.1 嵌套继承

A 持锁 X → B(高)等 X → A 提升。 A 又持锁 Y → C(更高)等 Y → A 再次提升。

优先级传递链(priority chain)。

3.2 限制

四、PCP(Priority Ceiling Protocol)

每个锁有一个”天花板优先级”= 所有可能持有者中的最高优先级。

任务获取锁时 → 立即提升到天花板优先级 → 保证不会被任何可能竞争者抢占。

优势:防止死锁(如果天花板设置正确)。 劣势:需要静态分析确定天花板。

五、Linux rt_mutex

// kernel/locking/rtmutex.c
struct rt_mutex {
    raw_spinlock_t wait_lock;
    struct rb_root_cached waiters;  // 按优先级排序
    struct task_struct *owner;
};

rt_mutex 实现 优先级继承

六、PREEMPT_RT 的转换

PREEMPT_RT 把 spinlock_trt_mutex_t

// 普通内核
spin_lock(&lock);  // 禁止抢占

// PREEMPT_RT
spin_lock(&lock);  // 实际是 rt_mutex_lock → 可睡眠 + 优先级继承

只有 raw_spinlock_t 保持真正自旋。

好处:所有内核锁路径都有优先级继承 → 系统级防止优先级反转。

七、glibc PI mutex

pthread_mutexattr_t attr;
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
pthread_mutex_init(&mutex, &attr);

底层用 PI futex → 内核 rt_mutex → 优先级继承。

八、DEADLINE 任务的反转

SCHED_DEADLINE 任务也可能遇到优先级反转:

当前内核对 DEADLINE + PI 的支持仍在演进。

九、案例

9.1 音频

JACK audio server 使用 RT 线程 → 锁竞争 → 优先级反转 → 音频卡顿(xrun)。

解决:lock-free ring buffer 或 PI mutex。

9.2 数据库

实时数据库(如 VoltDB)在 RT 调度下需要考虑锁的优先级反转。

十、小结


参考文献

工具


上一篇futex 下一篇形式化验证

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-18 · os

【操作系统百科】SCHED_FIFO/RR 与 PREEMPT_RT

Linux 里的实时:SCHED_FIFO/RR 提供优先级调度,但原版内核仍有不可抢占点。PREEMPT_RT 补丁集 20 年后(6.12)合入主线,把几乎所有 spinlock 变 rt_mutex、IRQ 变线程。本文讲 RT 调度语义、RT-throttling、cyclictest 基线、优先级继承、以及 RT 部署的陷阱。

2026-07-05 · os

【操作系统百科】实时 OS 巡礼

VxWorks/QNX/Zephyr 与 Linux PREEMPT_RT 的工程取舍——硬实时 vs 软实时、静态调度、ARINC-653 分区、安全认证(DO-178C)、最小内存占用。

2026-06-05 · os

【操作系统百科】线程化中断

把 IRQ handler 线程化——PREEMPT_RT 的核心改造之一。本文讲 request_threaded_irq、handler/thread_fn 分工、IRQF_ONESHOT、全线程化的延迟与吞吐代价、softirq 线程化趋势。

2026-05-31 · os

【操作系统百科】futex

glibc pthread_mutex 背后是 futex——用户态快路径无 syscall,竞争时才进内核。本文讲 FUTEX_WAIT/WAKE、PI futex、robust futex、futex2、requeue、安全补丁与工程陷阱。


By .