std::atomic - cppreference.com (original) (raw)

Defined in header
template< class T > struct atomic; (1) (since C++11)
template< class U > struct atomic<U*>; (2) (since C++11)
Defined in header
template< class U > struct atomic<std::shared_ptr<U>>; (3) (since C++20)
template< class U > struct atomic<std::weak_ptr<U>>; (4) (since C++20)
Defined in header <stdatomic.h>
#define _Atomic(T) /* see below */ (5) (since C++23)

Each instantiation and full specialization of the std::atomic template defines an atomic type. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races).

In addition, accesses to atomic objects may establish inter-thread synchronization and order non-atomic memory accesses as specified by std::memory_order.

std::atomic is neither copyable nor movable.

The compatibility macro _Atomic is provided in <stdatomic.h> such that _Atomic(T) is identical to std::atomic while both are well-formed.It is unspecified whether any declaration in namespace std is available when <stdatomic.h> is included. (since C++23)

Contents

[edit] Specializations

[edit] Primary template

The primary std::atomic template may be instantiated with any TriviallyCopyable type T satisfying both CopyConstructible and CopyAssignable. The program is ill-formed if any of following values is false:

struct Counters { int a; int b; }; // user-defined trivially-copyable type std::atomic cnt; // specialization for the user-defined type

std::atomic<bool> uses the primary template. It is guaranteed to be a standard layout struct and has a trivial destructor.

[edit] Partial specializations

The standard library provides partial specializations of the std::atomic template for the following types with additional properties that the primary template does not have:

  1. Partial specializations std::atomic<U*> for all pointer types. These specializations have standard layout, trivial default constructors,(until C++20) and trivial destructors. Besides the operations provided for all atomic types, these specializations additionally support atomic arithmetic operations appropriate to pointer types, such as fetch_add, fetch_sub.

[edit] Specializations for integral types

When instantiated with one of the following integral types, std::atomic provides additional atomic operations appropriate to integral types such as fetch_add, fetch_sub, fetch_and, fetch_or, fetch_xor:

Additionally, the resulting std::atomic<_Integral_> specialization has standard layout, a trivial default constructor,(until C++20) and a trivial destructor. Signed integer arithmetic is defined to use two's complement; there are no undefined results.

Specializations for floating-point types When instantiated with one of the cv-unqualified floating-point types (float, double, long double and cv-unqualified extended floating-point types(since C++23)), std::atomic provides additional atomic operations appropriate to floating-point types such as fetch_add and fetch_sub.Additionally, the resulting std::atomic<_Floating_> specialization has standard layout and a trivial destructor.No operations result in undefined behavior even if the result is not representable in the floating-point type. The floating-point environment in effect may be different from the calling thread's floating-point environment. (since C++20)

[edit] Member types

Type Definition
value_type T (regardless of whether specialized or not)
difference_type[1] value_type (only for atomic<_Integral_> and atomic<_Floating_>(since C++20) specializations) std::ptrdiff_t (only for std::atomic<U*> specializations)
  1. difference_type is not defined in the primary std::atomic template or in the partial specializations for std::shared_ptr and std::weak_ptr.

[edit] Member functions

(constructor) constructs an atomic object (public member function) [edit]
operator= stores a value into an atomic object (public member function) [edit]
is_lock_free checks if the atomic object is lock-free (public member function) [edit]
store atomically replaces the value of the atomic object with a non-atomic argument (public member function) [edit]
load atomically obtains the value of the atomic object (public member function) [edit]
operator T loads a value from an atomic object (public member function) [edit]
exchange atomically replaces the value of the atomic object and obtains the value held previously (public member function) [edit]
compare_exchange_weakcompare_exchange_strong atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not (public member function) [edit]
wait(C++20) blocks the thread until notified and the atomic value changes (public member function) [edit]
notify_one(C++20) notifies at least one thread waiting on the atomic object (public member function) [edit]
notify_all(C++20) notifies all threads blocked waiting on the atomic object (public member function) [edit]
Constants
is_always_lock_free[static] (C++17) indicates that the type is always lock-free (public static member constant) [edit]

[edit] Specialized member functions

Specialized for integral, floating-point(since C++20) and pointer types
fetch_add atomically adds the argument to the value stored in the atomic object and obtains the value held previously (public member function) [edit]
fetch_sub atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously (public member function) [edit]
operator+=operator-= adds to or subtracts from the atomic value (public member function) [edit]
Specialized for integral and pointer types only
fetch_max(C++26) atomically performs std::max between the argument and the value of the atomic object and obtains the value held previously (public member function) [edit]
fetch_min(C++26) atomically performs std::min between the argument and the value of the atomic object and obtains the value held previously (public member function) [edit]
operator++operator++(int)operator--operator--(int) increments or decrements the atomic value by one (public member function) [edit]
Specialized for integral types only
fetch_and atomically performs bitwise AND between the argument and the value of the atomic object and obtains the value held previously (public member function) [edit]
fetch_or atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously (public member function) [edit]
fetch_xor atomically performs bitwise XOR between the argument and the value of the atomic object and obtains the value held previously (public member function) [edit]
operator&=operator|=operator^= performs bitwise AND, OR, XOR with the atomic value (public member function) [edit]

[edit] Type aliases

Type aliases are provided for bool and all integral types listed above, as follows:

Aliases for all std::atomic
atomic_bool(C++11) std::atomic<bool> (typedef) [edit]
atomic_char(C++11) std::atomic<char> (typedef) [edit]
atomic_schar(C++11) std::atomic<signed char> (typedef) [edit]
atomic_uchar(C++11) std::atomic<unsigned char> (typedef) [edit]
atomic_short(C++11) std::atomic<short> (typedef) [edit]
atomic_ushort(C++11) std::atomic<unsigned short> (typedef) [edit]
atomic_int(C++11) std::atomic<int> (typedef) [edit]
atomic_uint(C++11) std::atomic<unsigned int> (typedef) [edit]
atomic_long(C++11) std::atomic<long> (typedef) [edit]
atomic_ulong(C++11) std::atomic<unsigned long> (typedef) [edit]
atomic_llong(C++11) std::atomic<long long> (typedef) [edit]
atomic_ullong(C++11) std::atomic<unsigned long long> (typedef) [edit]
atomic_char8_t(C++20) std::atomic<char8_t> (typedef) [edit]
atomic_char16_t(C++11) std::atomic<char16_t> (typedef) [edit]
atomic_char32_t(C++11) std::atomic<char32_t> (typedef) [edit]
atomic_wchar_t(C++11) std::atomic<wchar_t> (typedef) [edit]
atomic_int8_t(C++11)(optional) std::atomic<std::int8_t> (typedef) [edit]
atomic_uint8_t(C++11)(optional) std::atomic<std::uint8_t> (typedef) [edit]
atomic_int16_t(C++11)(optional) std::atomic<std::int16_t> (typedef) [edit]
atomic_uint16_t(C++11)(optional) std::atomic<std::uint16_t> (typedef) [edit]
atomic_int32_t(C++11)(optional) std::atomic<std::int32_t> (typedef) [edit]
atomic_uint32_t(C++11)(optional) std::atomic<std::uint32_t> (typedef) [edit]
atomic_int64_t(C++11)(optional) std::atomic<std::int64_t> (typedef) [edit]
atomic_uint64_t(C++11)(optional) std::atomic<std::uint64_t> (typedef) [edit]
atomic_int_least8_t(C++11) std::atomic<std::int_least8_t> (typedef) [edit]
atomic_uint_least8_t(C++11) std::atomic<std::uint_least8_t> (typedef) [edit]
atomic_int_least16_t(C++11) std::atomic<std::int_least16_t> (typedef) [edit]
atomic_uint_least16_t(C++11) std::atomic<std::uint_least16_t> (typedef) [edit]
atomic_int_least32_t(C++11) std::atomic<std::int_least32_t> (typedef) [edit]
atomic_uint_least32_t(C++11) std::atomic<std::uint_least32_t> (typedef) [edit]
atomic_int_least64_t(C++11) std::atomic<std::int_least64_t> (typedef) [edit]
atomic_uint_least64_t(C++11) std::atomic<std::uint_least64_t> (typedef) [edit]
atomic_int_fast8_t(C++11) std::atomic<std::int_fast8_t> (typedef) [edit]
atomic_uint_fast8_t(C++11) std::atomic<std::uint_fast8_t> (typedef) [edit]
atomic_int_fast16_t(C++11) std::atomic<std::int_fast16_t> (typedef) [edit]
atomic_uint_fast16_t(C++11) std::atomic<std::uint_fast16_t> (typedef) [edit]
atomic_int_fast32_t(C++11) std::atomic<std::int_fast32_t> (typedef) [edit]
atomic_uint_fast32_t(C++11) std::atomic<std::uint_fast32_t> (typedef) [edit]
atomic_int_fast64_t(C++11) std::atomic<std::int_fast64_t> (typedef) [edit]
atomic_uint_fast64_t(C++11) std::atomic<std::uint_fast64_t> (typedef) [edit]
atomic_intptr_t(C++11)(optional) std::atomic<std::intptr_t> (typedef) [edit]
atomic_uintptr_t(C++11)(optional) std::atomic<std::uintptr_t> (typedef) [edit]
atomic_size_t(C++11) std::atomic<std::size_t> (typedef) [edit]
atomic_ptrdiff_t(C++11) std::atomic<std::ptrdiff_t> (typedef) [edit]
atomic_intmax_t(C++11) std::atomic<std::intmax_t> (typedef) [edit]
atomic_uintmax_t(C++11) std::atomic<std::uintmax_t> (typedef) [edit]
Aliases for special-purpose types
atomic_signed_lock_free(C++20) a signed integral atomic type that is lock-free and for which waiting/notifying is most efficient (typedef) [edit]
atomic_unsigned_lock_free(C++20) an unsigned integral atomic type that is lock-free and for which waiting/notifying is most efficient (typedef) [edit]

Note: std::atomic_int_N__t, std::atomic_uint_N__t, std::atomic_intptr_t, and std::atomic_uintptr_t are defined if and only if std::int_N__t, std::uint_N__t, std::intptr_t, and std::uintptr_t are defined, respectively.

std::atomic_signed_lock_free and std::atomic_unsigned_lock_free are optional in freestanding implementations. (since C++20)

[edit] Notes

There are non-member function template equivalents for all member functions of std::atomic. Those non-member functions may be additionally overloaded for types that are not specializations of std::atomic, but are able to guarantee atomicity. The only such type in the standard library is std::shared_ptr<U>.

_Atomic is a keyword and used to provide atomic types in C.

Implementations are recommended to ensure that the representation of _Atomic(T) in C is same as that of std::atomic<T> in C++ for every possible type T. The mechanisms used to ensure atomicity and memory ordering should be compatible.

On GCC and Clang, some of the functionality described here requires linking against -latomic.

Feature-test macro Value Std Feature
__cpp_lib_atomic_ref 201806L (C++20) std::atomic_ref
__cpp_lib_constexpr_atomic 202411L (C++26) constexpr std::atomic and std::atomic_ref

[edit] Example

#include #include #include #include   std::atomic_int acnt; int cnt;   void f() { for (auto n{10000}; n; --n) { ++acnt; ++cnt; // Note: for this example, relaxed memory order is sufficient, // e.g. acnt.fetch_add(1, std::memory_order_relaxed); } }   int main() { { std::vector<std::jthread> pool; for (int n = 0; n < 10; ++n) pool.emplace_back(f); }   std::cout << "The atomic counter is " << acnt << '\n' << "The non-atomic counter is " << cnt << '\n'; }

Possible output:

The atomic counter is 100000 The non-atomic counter is 69696

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 2441 C++11 typedefs for atomic versions of optionalfixed width integer types were missing added
LWG 3012 C++11 std::atomic was permitted for any Tthat is trivially copyable but not copyable such specializations are forbidden
LWG 3949 C++17 the wording requiring std::atomic<bool> to have atrivial destructor was accidently dropped in C++17 added back
LWG 4069(P3323R1) C++11 support for cv-qualified T was questionable disallow T being cv-qualified
P0558R1 C++11 template argument deduction for somefunctions for atomic types might accidentlyfail; invalid pointer operations were provided specification was substantially rewritten:member typedefs value_typeand difference_type are added

[edit] See also