繁体   English   中英

std :: memory_order_relaxed和初始化

[英]std::memory_order_relaxed and initialization

是否可以保证以下各项打印1后跟2?

auto&& atomic = std::atomic<int>{0};
std::atomic<int>* pointer = nullptr;

// thread 1
auto&& value = std::atomic<int>{1};
pointer = &value;
atomic.store(1, std::memory_order_relaxed);
while (atomic.load(std::memory_order_relaxed) != 2) {}
cout << value.load(std::memory_order_relaxed) << endl;

// thread 2
while (atomic.load(std::memory_order_relaxed) != 1) {}
cout << pointer->load(std::memory_order_relaxed); << endl;
pointer->fetch_add(1, std::memory_order_relaxed);
atomic.store(2, std::memory_order_relaxed) {}

如果没有,这里可能的输出是什么? 在这种情况下,标准对初始化和存储顺序有何看法?

如评论中所述,使用“松弛”排序可防止发生任何必要的线程间同步,因此,对pointer访问是不同步的(或无序的)。
这意味着线程2可以取消引用pointer同时它仍具有值nullptr
同样,由于pointer是非原子类型的(即常规指针),因此可能无法在线程之间以这种方式访问​​它。 从技术上讲,您存在数据争用,这会导致未定义的行为。

一个解决方案是稍微增强内存排序。 我认为在atomic上使用获取/发布顺序应该足够了:

auto&& atomic = std::atomic<int>{0};
std::atomic<int>* pointer = nullptr;

// thread 1
auto&& value = std::atomic<int>{1};
pointer = &value;
atomic.store(1, std::memory_order_release);
while (atomic.load(std::memory_order_acquire) != 2) {}
cout << value.load(std::memory_order_relaxed) << endl;

// thread 2
while (atomic.load(std::memory_order_acquire) != 1) {}
cout << pointer->load(std::memory_order_relaxed); << endl;
pointer->fetch_add(1, std::memory_order_relaxed);
atomic.store(2, std::memory_order_release) {}

有了此订购,就可以保证打印出结果

1
2

暂无
暂无

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

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