修改并读取原子变量

时间:2018-04-11 15:25:41

标签: c++ multithreading c++11 c++14 atomic

一个类有以下成员,

std::atomic<int> clientId{0};

并在其内部成员函数

中给出以下内容
int currentId = ++clientId.load();

这里有竞争条件吗?我正在尝试做类似的事情来生成clientId&#39; s。多个线程可以执行这部分代码。一个线程已经增加了clientId并且在它尝试加载()并获得一个副本之前,另一个线程会增加相同的内容并因此最终会出现竞争条件吗? 如果是,使用普通int保护互斥锁是最好的方法并在互斥锁中获取副本?

请解释一下。

1 个答案:

答案 0 :(得分:4)

std::atomic<int>::load()不会返回引用,因此您不会递增clientId的当前值,而是递增load()返回的临时值。

你需要这样做:

int currentId = ++clientId; // no .load()

std::atomicoverloaded operators。预增量运算符的内存顺序为std:: memory_order_seq_cst 1 ,表示:

  

具有此内存顺序的加载操作执行获取操作,存储执行释放操作,读取 - 修改 - 写执行获取操作和释放操作,以及存在单个总订单,其中所有线程都观察到所有操作以相同的顺序进行修改(参见下面的顺序一致排序)

因此,您可以安全地摆脱数据竞争条件。

1 标准规定++clientId相当于fetch_add(1) + 1fetch_add的默认内存顺序为std::memory_order_seq_cst