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
Definido en el encabezado <atomic>
template < class T >
struct atomic ;
(1) (desde C++11)
template < class U >
struct atomic < U * > ;
(2) (desde C++11)
Definido en el encabezado <memory>
template < class U >
struct atomic < std:: shared_ptr < U >> ;
(3) (desde C++20)
template < class U >
struct atomic < std:: weak_ptr < U >> ;
(4) (desde C++20)
Definido en el encabezado <stdatomic.h>
#define _Atomic(T) /* ver más abajo */
(5) (desde C++23)

Cada instanciación y especialización completa de la plantilla std::atomic define un tipo atómico. Si un hilo escribe en un objeto atómico mientras otro hilo lo lee, el comportamiento está bien definido (consulte el modelo de memoria para más detalles sobre carreras de datos).

Además, los accesos a objetos atómicos pueden establecer sincronización entre hilos y ordenar accesos a memoria no atómicos según lo especificado por std::memory_order .

std::atomic no es copiable ni movible.

La macro de compatibilidad _Atomic se proporciona en <stdatomic.h> tal que _Atomic(T) es idéntica a std::atomic<T> cuando ambas están bien formadas.

No está especificado si alguna declaración en el espacio de nombres std está disponible cuando se incluye <stdatomic.h> .

(desde C++23)

Contenidos

Especializaciones

Plantilla principal

La plantilla principal std::atomic puede instanciarse con cualquier tipo TriviallyCopyable T que satisfaga tanto CopyConstructible como CopyAssignable . El programa está mal formado si alguno de los siguientes valores es false :

**Nota:** El contenido dentro de las etiquetas ` ` se ha conservado sin traducción ya que contiene código C++ y términos específicos del lenguaje, de acuerdo con las instrucciones proporcionadas.
struct Counters { int a; int b; }; // tipo definido por el usuario trivialmente copiable
std::atomic<Counters> cnt;         // especialización para el tipo definido por el usuario

std :: atomic < bool > utiliza la plantilla principal. Se garantiza que es una estructura de diseño estándar y tiene un destructor trivial .

Especializaciones parciales

La biblioteca estándar proporciona especializaciones parciales de la plantilla std::atomic para los siguientes tipos con propiedades adicionales que la plantilla principal no tiene:

2) Especializaciones parciales std::atomic<U*> para todos los tipos de puntero. Estas especializaciones tienen diseño estándar , constructores por defecto triviales, (hasta C++20) y destructores triviales. Además de las operaciones proporcionadas para todos los tipos atómicos, estas especializaciones adicionalmente soportan operaciones aritméticas atómicas apropiadas para tipos de puntero, como fetch_add , fetch_sub .
3,4) Especializaciones parciales std :: atomic < std:: shared_ptr < U >> y std :: atomic < std:: weak_ptr < U >> están disponibles para std::shared_ptr y std::weak_ptr .

Consulte std::atomic <std::shared_ptr> y std::atomic <std::weak_ptr> para más detalles.

(desde C++20)

Especializaciones para tipos integrales

Cuando se instancia con uno de los siguientes tipos integrales, std::atomic proporciona operaciones atómicas adicionales apropiadas para tipos integrales tales como fetch_add , fetch_sub , fetch_and , fetch_or , fetch_xor :

  • Los tipos de caracteres char , char8_t (desde C++20) , char16_t , char32_t , y wchar_t ;
  • Los tipos enteros con signo estándar: signed char , short , int , long , y long long ;
  • Los tipos enteros sin signo estándar: unsigned char , unsigned short , unsigned int , unsigned long , y unsigned long long ;
  • Cualquier tipo integral adicional requerido por los typedefs en el encabezado <cstdint> .

Además, la especialización resultante std::atomic< Integral > tiene diseño estándar , un constructor por defecto trivial, (hasta C++20) y un destructor trivial. La aritmética de enteros con signo está definida para usar complemento a dos; no hay resultados indefinidos.

Especializaciones para tipos de punto flotante

Cuando se instancia con uno de los tipos de punto flotante sin calificadores cv ( float , double , long double y tipos de punto flotante extendidos sin calificadores cv extended floating-point types (desde C++23) ), std::atomic proporciona operaciones atómicas adicionales apropiadas para tipos de punto flotante como fetch_add y fetch_sub .

Adicionalmente, la especialización resultante std::atomic< Floating > tiene diseño estándar y un destructor trivial.

Ninguna operación resulta en comportamiento indefinido incluso si el resultado no es representable en el tipo de punto flotante. El entorno de punto flotante en efecto puede ser diferente del entorno de punto flotante del hilo que realiza la llamada.

(desde C++20)

Tipos de miembros

Tipo Definición
value_type T (independientemente de si está especializado o no)
difference_type [1]

value_type (solo para especializaciones atomic< Integral > y atomic< Floating > (desde C++20) )

std::ptrdiff_t (solo para especializaciones std::atomic<U*> )

  1. difference_type no está definido en la plantilla principal std::atomic ni en las especializaciones parciales para std::shared_ptr y std::weak_ptr .

Funciones miembro

construye un objeto atómico
(función miembro pública)
almacena un valor en un objeto atómico
(función miembro pública)
verifica si el objeto atómico es libre de bloqueo
(función miembro pública)
reemplaza atómicamente el valor del objeto atómico con un argumento no atómico
(función miembro pública)
obtiene atómicamente el valor del objeto atómico
(función miembro pública)
carga un valor desde un objeto atómico
(función miembro pública)
reemplaza atómicamente el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
compara atómicamente el valor del objeto atómico con un argumento no atómico y realiza intercambio atómico si son iguales o carga atómica si no
(función miembro pública)
(C++20)
bloquea el hilo hasta que sea notificado y el valor atómico cambie
(función miembro pública)
(C++20)
notifica al menos un hilo esperando en el objeto atómico
(función miembro pública)
(C++20)
notifica todos los hilos bloqueados esperando en el objeto atómico
(función miembro pública)

Constantes

[static] (C++17)
indica que el tipo es siempre libre de bloqueo
(constante miembro estática pública)

Funciones miembro especializadas

Especializado para tipos integrales , de punto flotante (desde C++20) y punteros
agrega atómicamente el argumento al valor almacenado en el objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
resta atómicamente el argumento del valor almacenado en el objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
suma o resta del valor atómico
(función miembro pública)
Especializado solo para tipos integrales y punteros
(C++26)
realiza atómicamente std::max entre el argumento y el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
(C++26)
realiza atómicamente std::min entre el argumento y el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
incrementa o decrementa el valor atómico en uno
(función miembro pública)
Especializado solo para tipos integrales
realiza atómicamente AND bit a bit entre el argumento y el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
realiza atómicamente OR bit a bit entre el argumento y el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
realiza atómicamente XOR bit a bit entre el argumento y el valor del objeto atómico y obtiene el valor mantenido previamente
(función miembro pública)
realiza AND, OR, XOR bit a bit con el valor atómico
(función miembro pública)

Alias de tipos

Se proporcionan alias de tipo para bool y todos los tipos integrales mencionados anteriormente, de la siguiente manera:

Alias para todos 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 >
(typedef)
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 >
(typedef)
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 >
(typedef)
atomic_char16_t
(C++11)
std :: atomic < char16_t >
(typedef)
atomic_char32_t
(C++11)
std :: atomic < char32_t >
(typedef)
atomic_wchar_t
(C++11)
std :: atomic < wchar_t >
(typedef)
atomic_int8_t
(C++11) (opcional)
std :: atomic < std:: int8_t >
(typedef)
atomic_uint8_t
(C++11) (opcional)
std :: atomic < std:: uint8_t >
(typedef)
atomic_int16_t
(C++11) (opcional)
std :: atomic < std:: int16_t >
(typedef)
atomic_uint16_t
(C++11) (opcional)
std :: atomic < std:: uint16_t >
(typedef)
atomic_int32_t
(C++11) (opcional)
std :: atomic < std:: int32_t >
(typedef)
atomic_uint32_t
(C++11) (opcional)
std :: atomic < std:: uint32_t >
(typedef)
atomic_int64_t
(C++11) (opcional)
std :: atomic < std:: int64_t >
(typedef)
atomic_uint64_t
(C++11) (opcional)
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 >
(typedef)
atomic_int_least16_t
(C++11)
std :: atomic < std:: int_least16_t >
(typedef)
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 >
(typedef)
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 >
(typedef)
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 >
(typedef)
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 >
(typedef)
atomic_intptr_t
(C++11) (opcional)
std :: atomic < std:: intptr_t >
(typedef)
atomic_uintptr_t
(C++11) (opcional)
std :: atomic < std:: uintptr_t >
(typedef)
atomic_size_t
(C++11)
std :: atomic < std:: size_t >
(typedef)
atomic_ptrdiff_t
(C++11)
std :: atomic < std:: ptrdiff_t >
(typedef)
atomic_intmax_t
(C++11)
std :: atomic < std:: intmax_t >
(typedef)
atomic_uintmax_t
(C++11)
std :: atomic < std:: uintmax_t >
(typedef)
Alias para tipos de propósito especial
atomic_signed_lock_free
(C++20)
un tipo atómico entero con signo que no utiliza bloqueos y para el cual la espera/notificación es más eficiente
(typedef)
atomic_unsigned_lock_free
(C++20)
un tipo atómico integral sin signo que es libre de bloqueo y para el cual la espera/notificación es más eficiente
(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 y std::atomic_unsigned_lock_free son opcionales en implementaciones independientes.

(desde C++20)

Notas

Existen equivalentes de plantillas de funciones no miembro para todas las funciones miembro de std::atomic . Estas funciones no miembro pueden estar adicionalmente sobrecargadas para tipos que no son especializaciones de std::atomic , pero son capaces de garantizar atomicidad. El único tipo de este tipo en la biblioteca estándar es std:: shared_ptr < U > .

_Atomic es una palabra clave y se utiliza para proporcionar tipos atómicos en C.

Se recomienda que las implementaciones garanticen que la representación de _Atomic(T) en C sea la misma que la de std::atomic<T> en C++ para todo tipo posible T . Los mecanismos utilizados para garantizar atomicidad y ordenamiento de memoria deben ser compatibles.

En GCC y Clang, parte de la funcionalidad descrita aquí requiere enlazar con -latomic .

Macro de prueba de características Valor Estándar Característica
__cpp_lib_atomic_ref 201806L (C++20) std::atomic_ref
__cpp_lib_constexpr_atomic 202411L (C++26) constexpr std::atomic y std::atomic_ref

Ejemplo

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
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';
}

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2441 C++11 faltaban los typedefs para las versiones atómicas de los
tipos de enteros de ancho fijo opcionales
añadidos
LWG 3012 C++11 std::atomic<T> estaba permitido para cualquier T
que fuera trivialmente copiable pero no copiable
tales especializaciones están prohibidas
LWG 3949 C++17 la redacción que requería que std :: atomic < bool > tuviera un
destructor trivial se eliminó accidentalmente en C++17
restaurada
LWG 4069
( P3323R1 )
C++11 el soporte para T calificado con cv era cuestionable prohibir que T esté calificado con cv
P0558R1 C++11 la deducción de argumentos de plantilla para algunas
funciones de tipos atómicos podría fallar accidentalmente;
se proporcionaron operaciones de puntero inválidas
la especificación se reescribió sustancialmente:
se añadieron los typedefs miembro value_type
y difference_type

Véase también

el tipo atómico booleano libre de bloqueo
(clase)
puntero compartido atómico
(especialización de plantilla de clase)
puntero débil atómico
(especialización de plantilla de clase)
Documentación de C para Tipos atómicos