简体   繁体   中英

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. 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? If yes, is protecting with a mutex the best way using an ordinary int and getting a copy inside the mutex?

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() .

You need to do:

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

There are overloaded operators for std::atomic . The memory order for the pre-increment operator is std:: memory_order_seq_cst 1 , which says:

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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