使用memory_order_relaxed进行存储,并使用memory_order_acquire进行加载 [英] Using memory_order_relaxed for storing with memory_order_acquire for loading
问题描述
我对以下代码有疑问
#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x, y;
std::atomic<int> z;
void write_x_then_y()
{
x.store(true, std::memory_order_relaxed);
y.store(true, std::memory_order_relaxed);
}
void read_y_then_x()
{
while (!y.load(std::memory_order_acquire));
if (x.load(std::memory_order_acquire))
++z;
}
int main()
{
x = false;
y = false;
z = 0;
std::thread a(write_x_then_y);
std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load() != 0);
}
我可以确定assert(z.load()!= 0)始终为假吗? 我认为x.store和y.store不在数据提供者线程中重新排序(是吗?). 因此,我认为如果加载由x和y存储的值的线程使用memory_order_acquire,那么它是从执行存储操作符的内核缓存中获取x和y的实际值的.
Can i be sure about assert(z.load() != 0) is always be false? I think x.store and y.store is not reordered in data provider thread (that is true?). For this reason i think if thread which loading values stored by x and y uses memory_order_acquire, it was get actual values for x and y from cache of core which performs storing operators.
推荐答案
我认为断言可能会失败. std::memory_order_relaxed
允许编译器对write_x_then_y
中的存储重新排序. (例如,如果出于某种原因它认为会更快.)因此,它可能在x
之前写y
.整个read_y_then_x
可能在这两次写操作之间发生,因此它将观察到y
为true
,x
为false
并且不会递增z
.
I think the assert may fail. The std::memory_order_relaxed
allows the compiler to reorder the stores inside write_x_then_y
. (For example if it thinks it would be faster for any reason.) So it may write y
before x
. The whole read_y_then_x
may happen between those two writes and so it will observe y
being true
, x
being false
and it won't increment z
.
这篇关于使用memory_order_relaxed进行存储,并使用memory_order_acquire进行加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!