假设我有以下代码段:
std::atomic<int> a(0);
void thread1()
{
int x = a.fetch_add(1, std::memory_order_relaxed);
std::cout << x << std::endl;
}
void thread2()
{
int x = a.fetch_add(1, std::memory_order_relaxed);
std::cout << x << std::endl;
}
int main()
{
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
}
问题是:我可以获得0 0
吗?
这里两个线程都以放松的内存顺序读取和修改a
,因此看起来它们都可以看到a
的零值。但在实践中,我只看到0 1
或1 0
。
答案 0 :(得分:4)
不,0 0
是不可能的。宽松的内存顺序并不意味着操作不是原子的,0 0
发生的唯一方法是读 - 修改 - 写是非原子的。但由于std::atomic::fetch_add
原子操作,我们知道一次只能运行一个fetch_add
,因此只能0 1
或1 0
。