锁类型及其规则¶

锁类型及其规则¶

spinlock_t 和 rwlock_t¶

PREEMPT_RT 内核上 spinlock_t 和 rwlock_t 语义的更改有一些含义。 例如,在非 PREEMPT_RT 内核上,以下代码序列按预期工作

local_irq_disable();

spin_lock(&lock);

并且与以下代码完全等效

spin_lock_irq(&lock);

同样适用于 rwlock_t 和 _irqsave() 后缀变体。

在 PREEMPT_RT 内核上,此代码序列会中断,因为 RT-mutex 需要完全可抢占的上下文。 而是使用 spin_lock_irq() 或 spin_lock_irqsave() 及其解锁对应项。 如果中断禁用和锁定必须保持分离,PREEMPT_RT 会提供一种 local_lock 机制。 获取 local_lock 会将任务固定到 CPU,从而允许获取每个 CPU 的中断禁用锁之类的东西。 但是,仅应在绝对必要时使用此方法。

典型的场景是线程上下文中每个 CPU 变量的保护

struct foo *p = get_cpu_ptr(&var1);

spin_lock(&p->lock);

p->count += this_cpu_read(var2);

这是非 PREEMPT_RT 内核上的正确代码,但在 PREEMPT_RT 内核上,这会中断。spinlock_t 语义的 PREEMPT_RT 特定更改不允许获取 p->lock,因为 get_cpu_ptr() 隐式禁用抢占。 以下替换适用于两个内核

struct foo *p;

migrate_disable();

p = this_cpu_ptr(&var1);

spin_lock(&p->lock);

p->count += this_cpu_read(var2);

migrate_disable() 确保任务固定在当前 CPU 上,这反过来保证了对 var1 和 var2 的每个 CPU 的访问在任务保持可抢占的同时停留在同一个 CPU 上。

migrate_disable() 替换对于以下场景无效

func()

{

struct foo *p;

migrate_disable();

p = this_cpu_ptr(&var1);

p->val = func2();

这会中断,因为 migrate_disable() 不能防止来自抢占任务的重入。 这种情况的正确替换是

func()

{

struct foo *p;

local_lock(&foo_lock);

p = this_cpu_ptr(&var1);

p->val = func2();

在非 PREEMPT_RT 内核上,这通过禁用抢占来防止重入。 在 PREEMPT_RT 内核上,这通过获取底层每个 CPU 的自旋锁来实现。

相关推荐

捕鱼达人2等级称号一览
365bet亚洲官方网址

捕鱼达人2等级称号一览

2025-08-06 👁️ 1987
手机屏幕上钥匙图标神秘消失的完全指南!
365bet亚洲官方网址

手机屏幕上钥匙图标神秘消失的完全指南!

2025-10-10 👁️ 793
神奇宝贝传说:阿尔宙斯自然指南
bat365app手机版

神奇宝贝传说:阿尔宙斯自然指南

2026-01-06 👁️ 3348
英雄联盟psg是哪个国家的
365bet亚洲官方网址

英雄联盟psg是哪个国家的

2026-01-15 👁️ 3965
固特异和倍耐力轮胎哪个好?测评对比
bat365app手机版

固特异和倍耐力轮胎哪个好?测评对比

2025-08-02 👁️ 7297
怎么查社保卡属于哪里,社保卡在哪儿怎么查