Linux RT_MUTEX 图文详解释

优先级反转:

  • 低优先级任务 C 首先持锁;

  • 高优先级任务 A 之后也试图持锁,但是锁被 C 占用,所以 A 持锁失败;

  • 在 C 执行过程中,中等优先级任务 B 被唤醒,抢占了任务 C 的执行;

此后如果任务B一直无耻的占用CPU,则C就一直得不到运行,C得不到运行就无法释放锁导致最高优先级任务A也无法被运行。

通过优先级继承,当任务 A 持锁失败时,锁的 owner task(任务 C)临时的把优先级上升至和任务 A 一样的优先级,在释放锁时,将优先级进行恢复。

实现逻辑:

要实现优先级继承,内核需要维护一条 PI Chain,保存进程持有锁和等待锁的依赖关系。PI Chain 是一个树形结构:

  • 一个 task 可能持有 N 个 rt_mutex;

  • 每个 rt_mutex 只能被一个 task 持有;

  • 一个 rt_mutex 可能让 M 个 task 挂起;

  • 每个 task 只会挂起在一个 rt_mutex 上;

  • task 通过 pi_waiter 可以遍历到它持有的每个 rt_mutex 上挂起的最高优先级的 task(top_waiter)。

一个复杂的场景如下:

根据上述场景,则 PI Chain 如下:

上述例子中一共有 5 个 PI Chain:

  • Task D->Lock 2->Task B->Lock 1->Task A;

  • Task E->Lock 2->Task B->Lock 1->Task A;

  • Task F->Lock 3->Task B->Lock 1->Task A;

  • Task G->Lock 3->Task B->Lock 1->Task A;

  • Task C->Lock 1->Task A;

为了维护优先级关系,处于 PI Chain 中右端任务的优先级必须大于等于 PI Chain 中左端的任务们;

比如上述例子中:Task A 的优先级必须大于 Task B/C/D/E/F/G,Task B 的任务优先级必须大于 Task D/E/F/G;

上述例子使用链表实现的,目前的Linux代码中采用红黑树的方式组织rt_mutex_waiter,实现逻辑是一样的:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小虾米的Daddy

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值