给定这个伪代码,其中全局有一个原子 inta
初始化为 0:
线程 1:
// ... some code here (X) ...
a.store(1, relaxed);
futex_wake(&a);
线程 2:
if (futex_wait(&a, 1) == woken_up) {
assert(a.load(relaxed) == 1);
// ... some code here (Y) ...
}
忽略虚假唤醒的可能性;我们可以从上面的代码中推断出代码X
同步Y
吗?基本上,它归结为 futex 本身是否意味着在唤醒的等待中实现获取/释放语义。
一点上下文:TSAN 不理解 futex 系统调用(例如,请参见此处,此处)。
现在,通常,当使用 futex 来实现互斥锁、信号量或其他同步原语时,还有一个原子变量,它通过“锁定”端加载获取排序,并通过“解锁”存储在释放排序中边。(上面,我故意使用宽松的语义。)
该获取/释放足以实现同步,形式上是正确的,并且它被 TSAN 识别(它不会报告任何以这种方式实现的锁,例如 Qt 中的 QBasicMutex)。
这个问题主要是关于上面链接的论坛帖子中提供的建议,用获取/释放语义标记 futex 操作本身。这样的标记是否正确?
(我知道 C++ 抽象机对 . 一无所知futex
。它甚至对 pthreads 一无所知,但 TSAN 知道,并且知道例如发生在 apthread_create
之前的代码也发生在新创建的线程中运行的代码之前。在其他话说,这不是语言律师的问题……)