这种std :: atomic_thread_fence的使用是否正确?

时间:2014-06-10 18:38:34

标签: c++ multithreading

我想在构造函数中初始化一个字段,然后再也不要更改它。我希望保证在构造函数完成后,每次读取该字段都会读取初始化值,无论读取发生在哪个线程中。

基本上,我想要与Java中final字段相同的保证。

这就是我的尝试:

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

struct Foo
{
    Foo(int x) : x(x)
    {
        // ensure all writes are visible to other threads
        std::atomic_thread_fence(std::memory_order_release);
    }

    int x;
};

void print_x(Foo const& foo)
{
    // I don't think I need an aquire fence here, because the object is
    // newly constructed, so there cannot be any stale reads.
    std::cout << foo.x << std::endl;
}

int main()
{
    Foo foo(1);
    std::thread t(print_x, foo);
    t.join();
}
  • 是否保证始终打印1或线程t能够在未初始化状态下观察foo.x
  • 如果不使用成员初始值设定项x(x)而使用明确的作业this->x = x;,该怎么办?
  • 如果x不是int而是某种类型,会怎样?
  • 使x成为const int会改变与线程安全有关的任何内容吗?

1 个答案:

答案 0 :(得分:3)

基本上,如果其他一切都是正确的,那就不应该是 问题。初始化字段后,在访问之前 在任何线程中,您需要某种内存同步; 很清楚。否则,其他线程如何知道它 是建造的。如果在启动另一个之前初始化它 线程,然后创建线程将确保必要的 同步。 (这只在线程之间进行 创建和创建的线程。其他已经运行的线程 不同步。)之后,只要没有线程 修改该值,不需要同步。

关于你的代码,你不需要围栏,因为 value在任何其他线程之前初始化 创建并创建线程确保必要 同步。