正当我以为我已经掌握了原子知识时,我看到了另一篇文章。这是摘录自GCC wiki, under 总体总结:
-Thread 1- -Thread 2- -Thread 3-
y.store (20); if (x.load() == 10) { if (y.load() == 10)
x.store (10); assert (y.load() == 20) assert (x.load() == 10)
y.store (10)
}
释放/获取模式只需要所涉及的两个线程同步。这意味着同步值与其他线程不可交换。线程 2 中的断言仍然必须为 true,因为线程 1 和 2 与 x.load() 同步。线程 3 不参与此同步,因此当线程 2 和 3 使用 y.load() 同步时,线程 3 的断言可能会失败。线程 1 和 3 之间没有同步,因此不能为“x”假设任何值。
文章说线程 2 中的断言不会失败,但是线程 3 中的断言不会失败might.
我觉得这很令人惊讶。这是我的推理链,线程 3 断言不会失败——也许有人可以告诉我哪里错了。
- 线程 3 观察
y == 10
仅当线程 2 写入 10 时。
- 仅当线程 2 看到时才写入 10
x == 10
.
- 线程 2(或any线程)看到
x == 10
仅当线程 1 写入 10 时。任何线程都没有对 x 进行进一步更新。
- 由于线程 2 观察到
x == 10
,线程 3 也与线程 2 同步,应该观察x == 10
.
释放/获取模式只需要所涉及的两个线程同步。
有人可以指出这个仅限两方的要求的来源吗?我的理解(当然,也许是错误的)是生产者不知道它正在与谁同步。即,线程 1 不能说“我的更新仅适用于线程 2”。同样,线程 2 不能说“给我线程 1 的更新”。相反,发布了x = 10
线程 1 可供任何人观察,如果他们愿意的话。
Thus, x = 10
作为最后一次更新(由线程 1),任何从系统中任何地方发生的获取(通过传递同步确保)都保证观察到该写入,不是吗?
这意味着同步值与其他线程不可交换。
不管这是否属实,作者的意思可能是及物的, not 可交换的, right?
最后,如果我上面错了,我很想知道什么同步操作可以保证线程 3 的断言不会失败。