gpt4 book ai didi

c++ - std::atomic_thread_fence 的使用是否正确?

转载 作者:行者123 更新时间:2023-11-30 02:45:48 28 4
gpt4 key购买 nike

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

基本上,我想要与 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 是否会改变线程安全性?

最佳答案

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

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

关于c++ - std::atomic_thread_fence 的使用是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24148517/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com