一个类有以下成员,
std::atomic<int> clientId{0};
并在其内部成员函数
中给出以下内容int currentId = ++clientId.load();
这里有竞争条件吗?我正在尝试做类似的事情来生成clientId&#39; s。多个线程可以执行这部分代码。一个线程已经增加了clientId并且在它尝试加载()并获得一个副本之前,另一个线程会增加相同的内容并因此最终会出现竞争条件吗? 如果是,使用普通int保护互斥锁是最好的方法并在互斥锁中获取副本?
请解释一下。
答案 0 :(得分:4)
std::atomic<int>::load()
不会返回引用,因此您不会递增clientId
的当前值,而是递增load()
返回的临时值。
你需要这样做:
int currentId = ++clientId; // no .load()
std::atomic
有overloaded operators。预增量运算符的内存顺序为std:: memory_order_seq_cst
1 ,表示:
具有此内存顺序的加载操作执行获取操作,存储执行释放操作,读取 - 修改 - 写执行获取操作和释放操作,以及存在单个总订单,其中所有线程都观察到所有操作以相同的顺序进行修改(参见下面的顺序一致排序)
因此,您可以安全地摆脱数据竞争条件。
1 标准规定++clientId
相当于fetch_add(1) + 1
,fetch_add
的默认内存顺序为std::memory_order_seq_cst
。 子>