简体   繁体   English

修改和读取原子变量

[英]Modify and read from an atomic variable

A class has the following member, 一个班级有以下成员,

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

And given the following inside it's member function, 并在其成员函数中给出以下内容,

int currentId = ++clientId.load();

Is there a race condition here? 这里有比赛条件吗? I am trying to do something similar to generate clientId's. 我正在尝试做类似的事情来生成clientId。 Multiple threads could execute this part of the code. 多个线程可以执行这部分代码。 Can a thread that has incremented clientId and before it tries to load() and get a copy, another thread increment the same and thus end up with a race condition? 一个已经增加了clientId并且在尝试加载()并获取副本之前,另一个线程会增加相同值并因此导致竞争状态的线程是否可以? If yes, is protecting with a mutex the best way using an ordinary int and getting a copy inside the mutex? 如果是,使用互斥对象进行保护是使用普通int并在互斥对象内部获取副本的最佳方法吗?

Please explain. 请解释。

std::atomic<int>::load() does not return a reference, so you are not incrementing the current value of clientId , you are incrementing the temporary returned by load() . std::atomic<int>::load()不返回引用,因此您不会递增clientId的当前值,而是递增load()返回的临时值。

You need to do: 您需要做:

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

There are overloaded operators for std::atomic . std::atomic重载的运算符 The memory order for the pre-increment operator is std:: memory_order_seq_cst 1 , which says: 预递增运算符的内存顺序为std:: memory_order_seq_cst 1 ,它表示:

A load operation with this memory order performs an acquire operation, a store performs a release operation, and read-modify-write performs both an acquire operation and a release operation, plus a single total order exists in which all threads observe all modifications in the same order (see Sequentially-consistent ordering below) 以该内存顺序执行的装入操作执行获取操作,存储执行释放操作,而读-修改-写操作同时执行获取操作和释放操作,此外还存在一个总顺序,其中所有线程都观察到线程中的所有修改。相同的顺序(请参见下面的顺序一致的顺序)

So you are safe from data-race condition here. 因此,您在这里免受数据争用情况的影响。

1 The standard says that ++clientId is equivalent to fetch_add(1) + 1 , and the default memory order for fetch_add is std::memory_order_seq_cst . 1该标准说++clientId等效于fetch_add(1) + 1 ,并且fetch_add的默认内存顺序为std::memory_order_seq_cst

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

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