READ_ONCE 简介

READ_ONCE 是 Linux 内核中的一个重要宏定义,用于确保从内存中读取变量值时编译器不会对读取操作进行优化,从而保证读取操作的原子性[1][2]。这个宏在多线程、中断上下文或需要防止编译器优化的场景中尤为重要,可以确保数据的一致性和正确性。

READ_ONCE 的定义和工作原理

READ_ONCE 宏的定义如下:

#define READ_ONCE(x) (*(volatile typeof(x) *)&(x))

这个定义包含几个关键部分:

  • typeof(x):GNU 扩展,用于获取变量 x 的类型[1][2]
  • volatile:关键字告诉编译器不要对变量的读取进行优化,确保每次访问都直接从内存中读取[1][2]
  • &(x):获取变量 x 的地址[1][2]
  • *(...):对上述操作结果进行解引用,从而获取变量的值[1][2]

使用场景和示例

在多线程或中断上下文中,当需要读取共享变量并确保读取的是最新值时,可以使用 READ_ONCE:

int data;
// 在线程或中断上下文中读取 data 的值
int value = READ_ONCE(data);

这样可以保证每次读取 data 时都能获取到最新的值,避免编译器优化导致的问题[1][2]。

READ_ONCE 的保证与限制

READ_ONCE 提供以下保证:

  1. 强制编译器生成读指令,防止编译器优化掉读取操作[3][4]
  2. 确保从内存中直接读取变量的值,而不是使用寄存器中的缓存值[1][2]

然而,READ_ONCE 也有一些限制:

  1. 它仅保证读取操作的原子性和最新性,对于更复杂的并发控制,仍需要使用锁或其他同步机制[1][2]
  2. 尽管 READ_ONCE 强制编译器生成读指令,但它不强制编译器使用结果[3][4]
  3. 它不能保证 CPU 执行顺序,只能防止编译器优化[8]

与 WRITE_ONCE 的关系

对于写操作,Linux 内核中有对应的 WRITE_ONCE 宏,其定义方式和用途类似[1][2]。这两个宏共同工作,可以在内核编程中更安全地访问共享变量,避免数据竞争和内存一致性问题。

历史演变

从 Linux 内核 v4.15 开始,对 DEC Alpha 架构的 READ_ONCE() 添加了一个 smp_mb() 操作[4],这意味着在 DEC Alpha 上,READ_ONCE() 还会发出内存屏障指令,进一步保证内存访问的顺序性。

在早期,Linux 内核使用 ACCESS_ONCE() 宏,但后来被 READ_ONCE() 替代,主要是为了避免某些编译器的 bug[6]。

Citations:
[1] https://www.cnblogs.com/linhaostudy/p/18220391
[2] https://cloud.tencent.com/developer/article/2423158
[3] http://wangzhou.github.io/Linux%E5%86%85%E6%A0%B8memory-barrier%E6%96%87%E6%A1%A3%E5%AD%A6%E4%B9%A0/
[4] https://github.com/cncounter/translation/blob/master/tiemao_2020/46_Linux_Kernel_Memory_Barriers/README.md
[5] https://blog.csdn.net/shift_wwx/article/details/130082519
[6] https://blog.csdn.net/denglin12315/article/details/124584159
[7] https://cloud.tencent.com/developer/article/2146050
[8] https://juejin.cn/post/6844903479366909960

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值