std:: atomic
|
Определено в заголовочном файле
<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
не копируется и не перемещается.
|
Совместимый макрос
Не определено, доступны ли какие-либо объявления в пространстве имен
|
(since C++23) |
Содержание |
Специализации
Основной шаблон
Основной шаблон
std::atomic
может быть инстанцирован любым
TriviallyCopyable
типом
T
, удовлетворяющим требованиям как
CopyConstructible
, так и
CopyAssignable
. Программа является некорректной, если любое из следующих значений равно
false
:
- std:: is_trivially_copyable < T > :: value
- std:: is_copy_constructible < T > :: value
- std:: is_move_constructible < T > :: value
- std:: is_copy_assignable < T > :: value
- std:: is_move_assignable < T > :: value
- std:: is_same < T, typename std:: remove_cv < T > :: type > :: value
struct Counters { int a; int b; }; // пользовательский тривиально копируемый тип std::atomic<Counters> cnt; // специализация для пользовательского типа
std :: atomic < bool > использует основной шаблон. Гарантируется, что это структура стандартной компоновки и имеет тривиальный деструктор .
Частичные специализации
Стандартная библиотека предоставляет частичные специализации шаблона
std::atomic
для следующих типов с дополнительными свойствами, которых нет у основного шаблона:
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)
),
Кроме того, результирующая специализация
Ни одна операция не приводит к неопределённому поведению, даже если результат не представим в типе с плавающей точкой. Floating-point environment в действии может отличаться от окружения с плавающей точкой вызывающего потока. |
(since C++20) |
Типы членов
| Тип | Определение | ||||
value_type
|
T
(независимо от специализации)
|
||||
difference_type
[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_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) |
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.
|
|
(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++11)
|
безблокировочный булев атомарный тип
(класс) |
|
(C++20)
|
атомарный умный указатель с разделяемым владением
(специализация шаблона класса) |
|
(C++20)
|
атомарный слабый указатель
(специализация шаблона класса) |
|
Документация C
для
Атомарные типы
|
|