Namespaces
Variants

std:: atomic

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
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
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Определено в заголовочном файле <atomic>
template < class T >
struct atomic ;
(1) (since C++11)
template < class U >
struct atomic < U * > ;
(2) (since C++11)
Определено в заголовочном файле <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)
Определено в заголовочном файле <stdatomic.h>
#define _Atomic(T) /* see below */
(5) (since C++23)

Каждая инстанциация и полная специализация шаблона std::atomic определяет атомарный тип. Если один поток записывает данные в атомарный объект, в то время как другой поток читает из него, поведение является корректно определённым (см. модель памяти для подробностей о гонках данных).

Кроме того, доступы к атомарным объектам могут устанавливать межпоточную синхронизацию и упорядочивать неатомарные обращения к памяти, как указано в std::memory_order .

std::atomic не копируется и не перемещается.

Совместимый макрос _Atomic предоставляется в <stdatomic.h> таким образом, что _Atomic(T) идентичен std::atomic<T> когда оба варианта корректно формируются.

Не определено, доступны ли какие-либо объявления в пространстве имен std при включении <stdatomic.h> .

(since C++23)

Содержание

Специализации

Основной шаблон

Основной шаблон std::atomic может быть инстанцирован любым TriviallyCopyable типом T , удовлетворяющим требованиям как CopyConstructible , так и CopyAssignable . Программа является некорректной, если любое из следующих значений равно false :

**Примечание:** Весь текст внутри тегов ` ` сохранен без изменений, так как содержит C++ код и специфические термины, которые не подлежат переводу согласно вашим требованиям.
struct Counters { int a; int b; }; // пользовательский тривиально копируемый тип
std::atomic<Counters> cnt;         // специализация для пользовательского типа

std :: atomic < bool > использует основной шаблон. Гарантируется, что это структура стандартной компоновки и имеет тривиальный деструктор .

Частичные специализации

Стандартная библиотека предоставляет частичные специализации шаблона std::atomic для следующих типов с дополнительными свойствами, которых нет у основного шаблона:

2) Частичные специализации std::atomic<U*> для всех типов указателей. Эти специализации имеют стандартную компоновку , тривиальные конструкторы по умолчанию, (до C++20) и тривиальные деструкторы. Помимо операций, предоставляемых для всех атомарных типов, эти специализации дополнительно поддерживают атомарные арифметические операции, применимые к типам указателей, такие как fetch_add , fetch_sub .
3,4) Частичные специализации std :: atomic < std:: shared_ptr < U >> и std :: atomic < std:: weak_ptr < U >> предоставляются для std::shared_ptr и std::weak_ptr .

Смотрите std::atomic <std::shared_ptr> и std::atomic <std::weak_ptr> для подробностей.

(since C++20)

Специализации для целочисленных типов

При создании экземпляра с одним из следующих целочисленных типов, std::atomic предоставляет дополнительные атомарные операции, подходящие для целочисленных типов, такие как fetch_add , fetch_sub , fetch_and , fetch_or , fetch_xor :

  • Типы символов char , char8_t (начиная с C++20) , char16_t , char32_t и wchar_t ;
  • Стандартные знаковые целочисленные типы: signed char , short , int , long и long long ;
  • Стандартные беззнаковые целочисленные типы: unsigned char , unsigned short , unsigned int , unsigned long и unsigned long long ;
  • Любые дополнительные целочисленные типы, требуемые определениями в заголовке <cstdint> .

Кроме того, получившаяся специализация std::atomic< Integral > имеет стандартную компоновку , тривиальный конструктор по умолчанию, (до C++20) и тривиальный деструктор. Арифметика знаковых целых чисел определена как использующая дополнительный код; неопределённых результатов не возникает.

Специализации для типов с плавающей точкой

При инстанцировании одним из cv-неквалифицированных типов с плавающей точкой ( float , double , long double и cv-неквалифицированных extended floating-point types (since C++23) ), std::atomic предоставляет дополнительные атомарные операции, подходящие для типов с плавающей точкой, такие как fetch_add и fetch_sub .

Кроме того, результирующая специализация std::atomic< Floating > имеет стандартную компоновку и тривиальный деструктор.

Ни одна операция не приводит к неопределённому поведению, даже если результат не представим в типе с плавающей точкой. Floating-point environment в действии может отличаться от окружения с плавающей точкой вызывающего потока.

(since C++20)

Типы членов

Тип Определение
value_type T (независимо от специализации)
difference_type [1]

value_type (только для специализаций atomic< Integral > и atomic< Floating > (начиная с C++20) )

std::ptrdiff_t (только для специализаций std::atomic<U*> )

  1. difference_type не определён в основном шаблоне std::atomic или в частичных специализациях для std::shared_ptr и std::weak_ptr .

Функции-члены

создает атомарный объект
(public member function)
сохраняет значение в атомарный объект
(public member function)
проверяет, является ли атомарный объект lock-free
(public member function)
атомарно заменяет значение атомарного объекта неатомарным аргументом
(public member function)
атомарно получает значение атомарного объекта
(public member function)
загружает значение из атомарного объекта
(public member function)
атомарно заменяет значение атомарного объекта и получает ранее хранившееся значение
(public member function)
атомарно сравнивает значение атомарного объекта с неатомарным аргументом и выполняет атомарный обмен при равенстве или атомарную загрузку при неравенстве
(public member function)
(C++20)
блокирует поток до уведомления и изменения атомарного значения
(public member function)
(C++20)
уведомляет как минимум один поток, ожидающий атомарный объект
(public member function)
(C++20)
уведомляет все потоки, заблокированные в ожидании атомарного объекта
(public member function)

Константы

[static] (C++17)
указывает, что тип всегда является lock-free
(public static member constant)

Специализированные функции-члены

Специализировано для целочисленных , чисел с плавающей точкой (начиная с C++20) и указательных типов
атомарно добавляет аргумент к значению, хранящемуся в атомарном объекте, и получает ранее хранившееся значение
(публичная функция-член)
атомарно вычитает аргумент из значения, хранящегося в атомарном объекте, и получает ранее хранившееся значение
(публичная функция-член)
добавляет к атомарному значению или вычитает из него
(публичная функция-член)
Специализировано только для целочисленных и указательных типов
(C++26)
атомарно выполняет std::max между аргументом и значением атомарного объекта и получает ранее хранившееся значение
(публичная функция-член)
(C++26)
атомарно выполняет std::min между аргументом и значением атомарного объекта и получает ранее хранившееся значение
(публичная функция-член)
увеличивает или уменьшает атомарное значение на единицу
(публичная функция-член)
Специализировано только для целочисленных типов
атомарно выполняет побитовое И между аргументом и значением атомарного объекта и получает ранее хранившееся значение
(публичная функция-член)
атомарно выполняет побитовое ИЛИ между аргументом и значением атомарного объекта и получает ранее хранившееся значение
(публичная функция-член)
атомарно выполняет побитовое исключающее ИЛИ между аргументом и значением атомарного объекта и получает ранее хранившееся значение
(публичная функция-член)
выполняет побитовое И, ИЛИ, исключающее ИЛИ с атомарным значением
(публичная функция-член)

Псевдонимы типов

Для типа bool и всех перечисленных выше целочисленных типов предоставляются псевдонимы типов следующим образом:

**Перевод текста:** - `atomic_schar` → `atomic_schar` (не переводится, C++ термин) - `(C++11)` → `(C++11)` (не переводится, версия стандарта) - `std::atomic ` → `std::atomic ` (не переводится, C++ код) - `(typedef)` → `(псевдоним типа)` **Примечание:** В данном случае весь текст уже является C++ специфичными терминами и HTML-разметкой, поэтому переводу подлежит только пояснение "(typedef)", которое уже переведено как "(определение типа)". Остальной текст сохранен в оригинальном виде в соответствии с требованиями. **Примечание:** В данном фрагменте HTML не содержится переводимого текста, кроме технических терминов C++ (`atomic_long`, `std::atomic `), которые согласно требованиям не подлежат переводу. Все остальные элементы представляют собой HTML-разметку, атрибуты классов и технические обозначения, которые должны сохраняться в оригинальном виде. **Примечание:** В данном случае весь текст уже находится внутри HTML-тегов ` ` или содержит C++ специфические термины (`atomic_llong`, `std::atomic `), которые не подлежат переводу согласно вашим требованиям. Единственный текст, который мог бы быть переведен - это "(typedef)", но это технический термин, который в русскоязычной документации обычно оставляют на английском. **Примечание:** В данном случае весь текст, подлежащий переводу, состоит из технических терминов C++ (`atomic_wchar_t`, `std::atomic `) и стандартных обозначений (`(C++11)`, `(typedef)`), которые не переводятся согласно требованиям. HTML-разметка и содержимое тегов ` ` сохранены без изменений. **Примечание:** В данном случае весь текст, требующий перевода, состоит только из технических терминов C++ (`atomic_int_fast32_t`, `std::atomic `) и служебных обозначений (`(C++11)`, `(typedef)`), которые согласно требованиям не подлежат переводу. HTML-разметка и код внутри тегов сохранены без изменений.
Псевдонимы для всех std::atomic<Integral>
atomic_bool
(C++11)
std :: atomic < bool >
(typedef)
atomic_char
(C++11)
std :: atomic < char >
(typedef)
atomic_schar
(C++11)
std :: atomic < signed char >
(typedef)
atomic_uchar
(C++11)
std :: atomic < unsigned char >
(typedef)
atomic_short
(C++11)
std :: atomic < short >
(typedef)
atomic_ushort
(C++11)
std :: atomic < unsigned short >
(typedef)
atomic_int
(C++11)
std :: atomic < int >
(определение типа)
atomic_uint
(C++11)
std :: atomic < unsigned int >
(typedef)
atomic_long
(C++11)
std :: atomic < long >
(typedef)
atomic_ulong
(C++11)
std :: atomic < unsigned long >
(определение типа)
atomic_llong
(C++11)
std :: atomic < long long >
(typedef)
atomic_ullong
(C++11)
std :: atomic < unsigned long long >
(typedef)
atomic_char8_t
(C++20)
std :: atomic < char8_t >
(определение типа)
atomic_char16_t
(C++11)
std :: atomic < char16_t >
(определение типа)
atomic_char32_t
(C++11)
std :: atomic < char32_t >
(определение типа)
atomic_wchar_t
(C++11)
std :: atomic < wchar_t >
(typedef)
atomic_int8_t
(C++11) (опционально)
std :: atomic < std:: int8_t >
(typedef)
atomic_uint8_t
(C++11) (опционально)
std :: atomic < std:: uint8_t >
(typedef)
atomic_int16_t
(C++11) (опционально)
std :: atomic < std:: int16_t >
(typedef)
atomic_uint16_t
(C++11) (опционально)
std :: atomic < std:: uint16_t >
(typedef)
atomic_int32_t
(C++11) (опционально)
std :: atomic < std:: int32_t >
(typedef)
atomic_uint32_t
(C++11) (опционально)
std :: atomic < std:: uint32_t >
(typedef)
atomic_int64_t
(C++11) (опционально)
std :: atomic < std:: int64_t >
(typedef)
atomic_uint64_t
(C++11) (опционально)
std :: atomic < std:: uint64_t >
(typedef)
atomic_int_least8_t
(C++11)
std :: atomic < std:: int_least8_t >
(typedef)
atomic_uint_least8_t
(C++11)
std :: atomic < std:: uint_least8_t >
(определение типа)
atomic_int_least16_t
(C++11)
std :: atomic < std:: int_least16_t >
(определение типа)
atomic_uint_least16_t
(C++11)
std :: atomic < std:: uint_least16_t >
(typedef)
atomic_int_least32_t
(C++11)
std :: atomic < std:: int_least32_t >
(определение типа)
atomic_uint_least32_t
(C++11)
std :: atomic < std:: uint_least32_t >
(typedef)
atomic_int_least64_t
(C++11)
std :: atomic < std:: int_least64_t >
(typedef)
atomic_uint_least64_t
(C++11)
std :: atomic < std:: uint_least64_t >
(typedef)
atomic_int_fast8_t
(C++11)
std :: atomic < std:: int_fast8_t >
(определение типа)
atomic_uint_fast8_t
(C++11)
std :: atomic < std:: uint_fast8_t >
(typedef)
atomic_int_fast16_t
(C++11)
std :: atomic < std:: int_fast16_t >
(определение типа)
atomic_uint_fast16_t
(C++11)
std :: atomic < std:: uint_fast16_t >
(typedef)
atomic_int_fast32_t
(C++11)
std :: atomic < std:: int_fast32_t >
(typedef)
atomic_uint_fast32_t
(C++11)
std :: atomic < std:: uint_fast32_t >
(typedef)
atomic_int_fast64_t
(C++11)
std :: atomic < std:: int_fast64_t >
(typedef)
atomic_uint_fast64_t
(C++11)
std :: atomic < std:: uint_fast64_t >
(псевдоним типа)
atomic_intptr_t
(C++11) (опционально)
std :: atomic < std:: intptr_t >
(псевдоним типа)
atomic_uintptr_t
(C++11) (опционально)
std :: atomic < std:: uintptr_t >
(псевдоним типа)
atomic_size_t
(C++11)
std :: atomic < std:: size_t >
(typedef)
atomic_ptrdiff_t
(C++11)
std :: atomic < std:: ptrdiff_t >
(определение типа)
atomic_intmax_t
(C++11)
std :: atomic < std:: intmax_t >
(определение типа)
atomic_uintmax_t
(C++11)
std :: atomic < std:: uintmax_t >
(typedef)
Псевдонимы для специализированных типов
atomic_signed_lock_free
(C++20)
знаковый целочисленный атомарный тип без блокировок, для которого операции ожидания/уведомления наиболее эффективны
(typedef)
atomic_unsigned_lock_free
(C++20)
беззнаковый целочисленный атомарный тип без блокировок, для которого ожидание/уведомление наиболее эффективно
(typedef)
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 и std::atomic_unsigned_lock_free являются опциональными в независимых реализациях.

(since C++20)

Примечания

Для всех функций-членов шаблона std::atomic существуют эквиваленты в виде шаблонов нечленных функций. Эти нечленные функции могут быть дополнительно перегружены для типов, которые не являются специализациями std::atomic , но способны гарантировать атомарность. Единственным таким типом в стандартной библиотеке является std:: shared_ptr < U > .

_Atomic является ключевым словом и используется для предоставления атомарных типов в языке C.

Рекомендуется, чтобы реализации обеспечивали, чтобы представление _Atomic(T) в C совпадало с представлением std::atomic<T> в C++ для любого возможного типа T . Механизмы, используемые для обеспечения атомарности и порядка памяти, должны быть совместимы.

В GCC и Clang часть функциональности, описанной здесь, требует линковки с -latomic .

Макрос тестирования возможностей Значение Стандарт Функция
__cpp_lib_atomic_ref 201806L (C++20) std::atomic_ref
__cpp_lib_constexpr_atomic 202411L (C++26) constexpr std::atomic и std::atomic_ref

Пример

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
std::atomic_int acnt;
int cnt;
void f()
{
    for (auto n{10000}; n; --n)
    {
        ++acnt;
        ++cnt;
        // Примечание: для этого примера достаточно ослабленного порядка памяти,
        // например: 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';
}

Возможный вывод:

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

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 2441 C++11 отсутствовали typedef-ы для атомарных версий optional
целочисленных типов фиксированной ширины
добавлены
LWG 3012 C++11 std::atomic<T> был разрешён для любого T
тривиально копируемого, но не копируемого
такие специализации запрещены
LWG 3949 C++17 формулировка, требующая тривиальный деструктор для std :: atomic < bool >
была случайно удалена в C++17
возвращена обратно
LWG 4069
( P3323R1 )
C++11 поддержка cv-квалифицированного T была сомнительной запретить T с cv-квалификаторами
P0558R1 C++11 вывод аргументов шаблона для некоторых
функций атомарных типов мог случайно
завершаться неудачей; предоставлялись недопустимые операции с указателями
спецификация была существенно переписана:
добавлены члены-typedef-ы value_type
и difference_type

Смотрите также

безблокировочный булев атомарный тип
(класс)
атомарный умный указатель с разделяемым владением
(специализация шаблона класса)
атомарный слабый указатель
(специализация шаблона класса)
Документация C для Атомарные типы