c++ - 一个线程写入的值是否保证在不锁定该变量的情况下被另一个线程看到?

标签 c++ multithreading x86-64

我正在尝试了解 x86-64 机器上 C++ 中的一致性保证,以及这在其他平台上是否有所不同。具体来说,我想知道是否可以保证如果一个线程在下一个线程读取变量之前写入变量,我是否总能看到正确的值?我读过一些关于此的相互矛盾的信息。

这是一个示例,其中 Shared 在另一个线程中更新,只有当我们确定值已完成更新时,结果才会被读取。这会一直打印 1 吗?每次我测试它时它都有,但我无法通过示例真正证明它。

#include <iostream>
#include <thread>
#include <atomic>

std::atomic<bool> Done {false};
int Shared = 0;

int main(int argc, const char* argv[])
{
    auto Thread = std::thread([](){
        Shared = 1;
        Done = true;
    });

    while(!Done)
    {
    }

    std::cout << Shared << std::endl;

    Thread.join();
    return 0;
}

此博客似乎建议在 x86-64 上所有写入都对其他线程可见:http://benbowen.blog/post/cmmics_iii/

这份文件听起来也像是在说类似的话:

When a thread is writing to a shared memory location, the MESIF protocol requires that all other copies of the memory location is invalidated. If this occurs, all cores in the processor sends a RFO­request (read­for­ownership request) to the LLC (in this case the L3­cache) that checks the snoop­filter and then sends out invalidations to all cache’s that holds a copy of the cache line.

https://www.eit.lth.se/fileadmin/eit/courses/edt621/Rapporter/2015/robin.skafte.pdf

最佳答案

这很复杂,但在您的特定情况下,这保证适用于所有 C++ 实现。

原因是 std::atomic 上操作的默认内存顺序是 std::memory_order_seq_cst,这确实保证了释放/获取语义。

具体来说,这意味着线程在释放存储之前对内存所做的任何写入(包括顺序一致的存储,比如你的)对于在同一原子上获取加载的任何线程都是可见的(包括顺序一致的加载,比如你的)并观察新值。

关于c++ - 一个线程写入的值是否保证在不锁定该变量的情况下被另一个线程看到?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57897843/

相关文章:

c++ - 计算圆、矩形和三角形坐标内的点 C++

c# - 其他对象引发的工作事件时的跨线程操作

c# - 如何使 IObservable<T> 的实现成为多线程的?

c++ - 是否可以将 Arduino Sketch 用作 C++ 程序?

C++/SDL,井字轮流

assembly - 在内存位置调用 `add` 是否比在寄存器上调用它然后移动值更快?

gcc - 64 位整数的 cmpxchg 示例

c - 在 Linux 内核中混合汇编和 C 函数 - x64 模式

c++ - LNK2005:找到用/MT构建的模块

python - 在 Django/mod_wsgi 中进行一次性初始化的安全方法是什么?