c++ - InterlockedExchange 和内存可见性

标签 c++ windows winapi atomic interlocked

我已阅读文章Synchronization and Multiprocessor Issues 我对 InterlockedCompareExchange 和 InterlockedExchange 有疑问。问题实际上是关于文章中的最后一个例子。它们有两个变量 iValuefValueHasBeenComputed 并且在 CacheComputedValue() 中它们使用 InterlockedExchange 修改它们中的每一个:

InterlockedExchange ((LONG*)&iValue, (LONG)ComputeValue());  // don't understand
InterlockedExchange ((LONG*)&fValueHasBeenComputed, TRUE); // understand

我知道我可以使用 InterlockedExchange 来修改 iValue 但它是否足够

iValue = ComputeValue();

那么真的有必要使用InterlockedExchange来设置iValue吗?或者即使 iValue = ComputeValue(); 其他线程也会正确地看到 iValue。我的意思是其他线程会正确地看到 iValue,因为它后面有 InterlockedExchange

还有论文A Principle-Based Sequential Memory Model for Microsoft Native Code Platforms .有 3.1.1 示例,代码大致相同。建议之一 Make y interlocked。注意 - 不是 yx

更新
只是为了澄清这个问题。问题是我看到了矛盾。 “同步和多处理器问题”中的示例使用了两个 InterlockedExchange。相反,在示例 3.1.1 “Basic Reodering”(我认为与第一个示例非常相似)中,Herb Sutter 给出了这个建议

"Make y interlocked: If y is interlocked, then there is no race on y because it is atomically updatable,and there is no race on x because a -> b -> d."

.在这个草稿中,Herb 没有使用两个互锁变量(如果我是对的,他的意思是 InterlockedExchange 仅用于 y )。

最佳答案

如果 iValue 的地址未与保证原子访问的地址对齐,他们这样做是为了防止部分读取/写入。当两个或多个物理线程尝试同时写入值,或者一个读取一个尝试同时写入时,就会出现此问题。

作为次要点,应该注意存储并不总是全局可见的,它们仅在序列化时可见,无论是通过栅栏还是通过总线锁。

关于c++ - InterlockedExchange 和内存可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7685516/

相关文章:

C++ 如何从虚拟设备中获取文件夹和文件名?

c++ - 使用参数类型的值在尾随返回中需要 decltype

c++ - lambda 的捕获机制

C++ Stringstream 给变量赋了错误的值?

java - 无法在 Windows 10 上执行 MySQL 转储,IDE 为 Netbeans 8.2

c - Windows 中的 ReadFile()

javascript - 如何通过javascript自定义activeX警告栏的位置

listview - 我的子类过程中未收到 WM_LBUTTONUP

winapi - GetFullPathName 是否适用于长于 MAX_PATH 的相对路径?

c++ - 使用动态库 qpOASES 和 CMakeList.txt 时出现 undefined reference to qpOASES 错误