Namespaces
Variants
Views
Actions

std::atomic

From cppreference.com
< cpp‎ | atomic
 
 
Concurrency support library
Threads
(C++11)
(C++20)
(C++20)
this_thread namespace
(C++11)
(C++11)
(C++11)
Mutual exclusion
(C++11)
(C++11)  
Generic lock management
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
(C++11)
Safe Reclamation
(C++26)
(C++26)
Hazard Pointers

Atomic types
atomic
(C++11)
(C++20)
Initialization of atomic types
(C++11)(deprecated in C++20)
(C++11)(deprecated in C++20)
Memory ordering
Free functions for atomic operations
Free functions for atomic flags
 
 
Defined in header <atomic>
template< class T >
struct atomic;
(1) (since C++11)
template< class U >
struct atomic<U*>;
(2) (since C++11)
Defined in header <memory>
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<T> 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<Counters> 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:

2) 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.
3,4) Partial specializations std::atomic<std::shared_ptr<U>> and std::atomic<std::weak_ptr<U>> are provided for std::shared_ptr and std::weak_ptr.

See std::atomic<std::shared_ptr> and std::atomic<std::weak_ptr> for details.

(since C++20)

[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:

  • The character types char, char8_t(since C++20), char16_t, char32_t, and wchar_t;
  • The standard signed integer types: signed char, short, int, long, and long long;
  • The standard unsigned integer types: unsigned char, unsigned short, unsigned int, unsigned long, and unsigned long long;
  • Any additional integral types needed by the typedefs in the header <cstdint>.

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] Type aliases

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

Aliases for all std::atomic<Integral>
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_intN_t, std::atomic_uintN_t, std::atomic_intptr_t, and std::atomic_uintptr_t are defined if and only if std::intN_t, std::uintN_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] Member types

Member type Definition
value_type T (regardless of whether specialized or not)
difference_type value_type (only for atomic<Integral> and atomic<Floating>(since C++20) specializations)
std::ptrdiff_t (only for std::atomic<U*> specializations)

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

constructs an atomic object
(public member function) [edit]
stores a value into an atomic object
(public member function) [edit]
checks if the atomic object is lock-free
(public member function) [edit]
atomically replaces the value of the atomic object with a non-atomic argument
(public member function) [edit]
atomically obtains the value of the atomic object
(public member function) [edit]
loads a value from an atomic object
(public member function) [edit]
atomically replaces the value of the atomic object and obtains the value held previously
(public member function) [edit]
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]
(C++20)
blocks the thread until notified and the atomic value changes
(public member function) [edit]
notifies at least one thread waiting on the atomic object
(public member function) [edit]
notifies all threads blocked waiting on the atomic object
(public member function) [edit]

Constants

[static] (C++17)
indicates that the type is always lock-free
(public static member constant) [edit]

[edit] Specialized member functions

atomically adds the argument to the value stored in the atomic object and obtains the value held previously
(public member function) [edit]
atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously
(public member function) [edit]
atomically performs bitwise AND between the argument and the value of the atomic object and obtains the value held previously
(public member function) [edit]
atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously
(public member function) [edit]
atomically performs bitwise XOR between the argument and the value of the atomic object and obtains the value held previously
(public member function) [edit]
increments or decrements the atomic value by one
(public member function) [edit]
adds, subtracts, or performs bitwise AND, OR, XOR with the atomic value
(public member function) [edit]

[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.

[edit] Example

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
 
std::atomic_int acnt;
int cnt;
 
void f()
{
    for (int n = 0; n < 10000; ++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 optional
fixed width integer types were missing
added
LWG 3012 C++11 std::atomic<T> was permitted for any T
that is trivially copyable but not copyable
such specializations are forbidden
LWG 3949 C++17 the wording requiring std::atomic<bool> to have a
trivial destructor was accidently dropped in C++17
added back
P0558R1 C++11 template argument deduction for some
functions for atomic types might accidently
fail; invalid pointer operations were provided
specification was substantially rewritten:
member typedefs value_type
and difference_type are added

[edit] See also

the lock-free boolean atomic type
(class) [edit]
atomic shared pointer
(class template specialization) [edit]
atomic weak pointer
(class template specialization) [edit]
C documentation for Atomic types