简体   繁体   English

获取/释放语义不能与其他线程交换

[英]On acquire/release semantics not being commutative to other threads

The gcc wiki here provides an example on memory ordering constraints.此处的 gcc wiki 提供了有关 memory 排序约束的示例。

In the below example, the wiki asserts that, if the memory ordering in use is an acquire/release, then thead-2 's assert is guaranteed to succeed while thread-3 's assert can fail.在下面的示例中,wiki 断言,如果使用的 memory 顺序是获取/释放,则thead-2的断言保证成功,而thread-3的断言可能失败。

 -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)
                  }

I don't see how that is possible.我不明白这怎么可能。 My understanding is that since Thread-2 's y.store(10) synchronizes with Thread-3 's y.load() and since y can be 10 if and only if x is 10 , I say the assert in Thread-3 should succeed.我的理解是,由于Thread-2y.store(10)Thread-3y.load() ) 同步,并且当且仅当x10y可以为10 ,所以我说Thread-3中的assert应该成功。 The wiki disagrees.维基不同意。 Can someone explain why?有人可以解释为什么吗?

and since y can be 10 if and only if x is 10,并且因为当且仅当 x 是 10 时 y 可以是 10,

And that's the part that is incorrect.那是不正确的部分。

An acquire/release pair works between a releasing store operation and an acquiring load operation which reads the value that was release-stored.获取/释放对在释放存储操作和读取释放存储值的获取加载操作之间工作。

In thread 1, we have a releasing store to x .在线程 1 中,我们有一个释放存储到x In thread 2, we have an acquiring load from x .在线程 2 中,我们有一个来自x的获取负载。 If thread 2 read the value stored by thread 1, then the two threads have an acquire/release relationship.如果线程2读取了线程1存储的值,那么这两个线程就有了acquire/release关系。 What that means is that any values written to other objects in thread 1 before the releasing store are visible to thread 2 after its acquiring load.这意味着在释放存储之前写入线程 1 中其他对象的任何值在线程 2 获取加载后都是可见的。

In thread 2, we have a releasing store to y .在线程 2 中,我们有一个释放存储到y In thread 3, we have an acquiring load from y .在线程 3 中,我们有一个来自y的获取负载。 If thread 3 read the value stored by thread 2, then the two threads have an acquire/release relationship.如果线程3读取了线程2存储的值,那么这两个线程就有了获取/释放的关系。 What that means is that any values written to other objects in thread 2 before the releasing store are visible to thread 3 after its acquiring load.这意味着在释放存储之前写入线程 2 中其他对象的任何值在线程 3 获取加载后都是可见的。

But notice what I said: "any values written to other objects in thread 2 ".但请注意我所说的:“写入线程 2 中其他对象的任何值”。

x was not written by thread 2; x不是由线程 2 编写的; it was written by thread 1. And thread 3 has no relationship to thread 1.它是由线程 1 编写的。线程 3 与线程 1 没有任何关系。

Pure acquire/release is not transitive.纯获取/释放是不可传递的。 If you need transitive access to memory, then you need sequential consistency.如果您需要对 memory 的传递访问,那么您需要顺序一致性。 Indeed, that's what seq_cst is for: ensuring consistently across all acquire/releases which transitively rely on each other.事实上,这就是seq_cst的目的:确保在所有相互依赖的获取/发布中保持一致。

Note that this is primarily about caches.请注意,这主要是关于缓存的。 A pure acquire/release operation may only flush certain caches, particularly if the compiler can clearly see exactly what memory a thread is making available in a release.纯粹的获取/释放操作可能只会刷新某些缓存,特别是如果编译器可以清楚地看到线程在释放中提供的内容 memory 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM