c - 实际示例中的 READ_ONCE 和 WRITE_ONCE
问题描述
int __thread theft = 0;
static void flush_local_count_sig(int unused)
{
if (READ_ONCE(theft) != THEFT_REQ) (*)
return;
smp_mb();
WRITE_ONCE(theft, THEFT_ACK)
if (!counting) {
WRITE_ONCE(theft, THEFT_READY);
}
smp_mb();
}
在416 页的https://mirrors.edge.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.2018.12.08a.pdf中有一个问题:
为什么要使用 theft per-thread 变量
READ_ONCE
并进行包装?WRITE_ONCE
答案是
第一个(用 (*) 注释)可以被认为是不必要的。
为什么第一个READ_ONCE
不是必需的?毕竟,编译器可以尝试过于聪明并对其进行优化。
int __thread theft = 0;
static void flush_local_count_sig(int unused)
{
if (theft != THEFT_REQ)
return;
smp_mb(); (*)
WRITE_ONCE(theft, THEFT_ACK)
if (!counting) {
WRITE_ONCE(theft, THEFT_READY);
}
smp_mb();
}
theft
不是同时访问的——它由一个线程和信号处理程序访问。如果我们删除带有 (*) 注释的行,那么正确性如何?
解决方案
推荐阅读
- javascript - TypeError:刷新或操作后无法读取属性
- javascript - 全屏隐藏播放器控件
- python - Python函数为列表中的每个区域创建一个图
- php - 分页不显示数据库中的最后两条数据
- python - Kivy,使用函数并获取随机信息到文本输入和随机图像?
- vuejs2 - VueJS 在操作之前处理完整的模板
- reactjs - 可以在没有后端的情况下从 SendGrid 和 React.js 发送电子邮件吗?
- java - KieScanner 无法从自定义 Maven 存储库中获取最新的罐子 - Maven - 3.6.3
- gradle - 如果某些类的测试发现失败,如何使 Junit 平台测试失败?
- ios - Crashlytics 不在 iOS 上发送事件