std::atomic is a template that allows you to declare its contained value to be atomic: access to this value from different threads is well defined and does not lead to data races.
How to set values
std::atomic is not copyable and not movable.
Lets say we need an atomic value as a class member and want it to be set to a default value:
#include <atomic>
class Foo {
std::atomic<bool> _online = true; // intuitive, but doesn't work
}
That doesn’t compile. Clang will tell us: "copying member subobject of type 'std::atomic_bool' (aka 'atomic<bool>') invokes deleted constructor."
Use the initialization constructor
Default values to atomic members can be assigned using an initializer list {} (braced initializer, or C++11 brace-init):
std::atomic<bool> _online{true};
For the complete API, refer to https://www.cplusplus.com/reference/atomic/atomic/
Aliases
And for those who want to improve readability a bit more, there are aliases we can use:
std::atomic_bool _online{true};
std::atomic_short
std::atomic_ushort
std::atomic_int
std::atomic_uint
std::atomic_long
std::atomic_ulong
std::atomic_llong
std::atomic_ullong
std::atomic_char8_t
std::atomic_char16_t
std::atomic_char32_t
std::atomic_wchar_t
std::atomic_int8_t
std::atomic_uint8_t
std::atomic_int16_t
std::atomic_uint16_t
std::atomic_int32_t
std::atomic_uint32_t
std::atomic_int64_t
std::atomic_uint64_t
std::atomic_int_least8_t
std::atomic_uint_least8_t
std::atomic_int_least16_t
std::atomic_uint_least16_t
std::atomic_int_least32_t
std::atomic_uint_least32_t
std::atomic_int_least64_t
std::atomic_uint_least64_t
std::atomic_int_fast8_t
std::atomic_uint_fast8_t
std::atomic_int_fast16_t
std::atomic_uint_fast16_t
std::atomic_int_fast32_t
std::atomic_uint_fast32_t
std::atomic_int_fast64_t
std::atomic_uint_fast64_t
std::atomic_intptr_t
std::atomic_uintptr_t
std::atomic_size_t
std::atomic_ptrdiff_t
std::atomic_intmax_t
std::atomic_uintmax_t
Tools
To detect data races you can use ThreadSanitizer, for example when you run your automated tests. It will tell you where to optimize your code.
clang++ -fsanitize=thread
And in cmake:
cmake -DCMAKE_C_FLAGS="-fsanitize=thread"
More about tsan here: https://clang.llvm.org/docs/ThreadSanitizer.html