Espacios de nombres
Variantes
Acciones

std::atomic<std::shared_ptr>

De cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Biblioteca de servicios
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
(C++20)
(C++11)
(C++11)
 
 
Definido en el archivo de encabezado <memory>
template <class T> struct std::atomic<std::shared_ptr<T>>;
(desde C++20)

La especialización de plantilla parcial de std::atomic para std::shared_ptr<T> permite a los usuarios manipular objetos shared_ptr atómicamente.

Si múltiples hilos de ejecución acceden el mismo objeto std::shared_ptr sin sincronización y cualquiera de esos accesos utiliza una función miembro no const de shared_ptr entonces ocurrirá una carrera de datos a menos que dicho acceso se realice a través de una instancia de std::atomic<std::shared_ptr> (o, en desuso a partir de C++20, a través de funciones independientes para acceso atómico a std::shared_ptr).

Se garantiza que los incrementos de use_count asociados sean parte de la operación atómica. Los decrementos de use_count asociados se secuencian después de la operación atómica, pero no es necesario que formen parte de ella, excepto por el cambio de use_count al anular expected en un CAS (Column Address Strobe) fallido. Cualquier eliminación y desasignación asociadas se secuencian después del paso de actualización atómica y no forman parte de la operación atómica.

Ten en cuenta que el bloque de control de shared_ptr es seguro para hilos: se puede acceder a diferentes objetos std::shared_ptr no atómicos mediante operaciones mutables, como operator = o reset, simultáneamente por varios hilos, incluso cuando estas instancias son copias, y comparten el mismo bloque de control internamente.

El tipo T puede ser un tipo incompleto.

Contenido

[editar] Tipos miembro

Tipo miembro Definición
value_type std::shared_ptr<T>

[editar] Funciones miembro

Esta especialización también proporciona todas las funciones std::atomic no especializadas y ninguna función miembro adicional.

atomic<shared_ptr<T>>::atomic

constexpr atomic() noexcept = default;
(1)
constexpr atomic( std::nullptr_t ) noexcept : atomic() {}
(2)
atomic( std::shared_ptr<T> desired ) noexcept;
(3)
atomic( const atomic& ) = delete;
(4)
1,2) Inicializa el shared_ptr<T> subyacente al valor nulo.
3) Inicializa el shared_ptr<T> subyacente a una copia de desired. Como con cualquier tipo std::atomic, la inicialización no es una operación atómica.
4) Los tipos atómicos no son construibles por copia o movimiento.

atomic<shared_ptr<T>>::operator=

void operator=( const atomic& ) = delete;
(1)
void operator=( std::shared_ptr<T> desired ) noexcept;
(2)
1) Los tipos atómicos no son asignables por copia o movimiento.
2) Asignación por valor, equivalente a store(desired)

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

Devuelve true si las operaciones atómicas en todos los objetos de este tipo están libres de bloqueo, false de lo contrario.

atomic<shared_ptr<T>>::store

void store( std::shared_ptr<T> desired,
            std::memory_order order = std::memory_order_seq_cst ) noexcept;

Reemplaza atómicamente el valor de *this con el valor de desired como si fuera por p.swap(desired) donde p es el std::shared_ptr<T> subyacente. La memoria se ordena de acuerdo con order. El comportamiento no está definido si order es std::memory_order_consume, std::memory_order_acquire, o std::memory_order_acq_rel.

atomic<shared_ptr<T>>::load

Devuelve atómicamente una copia del std::shared_ptr<T> subyacente. La memoria se ordena de acuerdo con order. El comportamiento no está definido si order es std::memory_order_release o std::memory_order_acq_rel.

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

operator std::shared_ptr<T>() const noexcept;

Equivalente a return load();

atomic<shared_ptr<T>>::exchange

std::shared_ptr<T> exchange( std::shared_ptr<T> desired,
                             std::memory_order order = std::memory_order_seq_cst ) noexcept;

Reemplaza atómicamente el std::shared_ptr<T> subyacente con desired como si fuera por p.swap(desired) donde p es el std::shared_ptr<T> subyacente y devuelve una copia del valor que p tenía inmediatamente antes del intercambio. La memoria se ordena de acuerdo con order. Esta es una operación atómica de lectura-modificación-escritura.

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                              std::memory_order success, std::memory_order failure ) noexcept;
(1)
bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                            std::memory_order success, std::memory_order failure ) noexcept;
(2)
bool compare_exchange_strong( std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                              std::memory_order order = std::memory_order_seq_cst ) noexcept;
(3)
bool compare_exchange_weak( std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                            std::memory_order order = std::memory_order_seq_cst ) noexcept;
(4)
1) Si el std::shared_ptr<T> subyacente almacena el mismo T* que expected y comparte posesión con él, o si tanto el subyacente como expected están vacíos, asigna de desired al std::shared_ptr<T> subyacente, devuelve true, y ordena la memoria de acuerdo con success, de lo contrario asigna del std::shared_ptr<T> subyacente a expected, devuelve false, y ordena la memoria de acuerdo con failure. El comportamiento no está definido si failure es std::memory_order_release o std::memory_order_acq_rel. En caso de éxito, la operación es una operación atómica de lectura-modificación-escritura en *this y expected no se accede después de la actualización atómica. En caso de falla, la operación es una operación de carga atómica en *this y expected se actualiza con el valor existente leído del objeto atómico. Esta actualización a use_count de expected es parte de esta operación atómica, aunque no se requiere que la escritura en sí misma (y cualquier desasignación/destrucción posterior) lo sea.
2) Igual que (1), pero también puede fallar espuriamente.
3) Equivalente a: return compare_exchange_strong(expected, desired, order, fail_order);, donde fail_order es igual que order excepto que std:memory_order_acq_rel se reemplaza por std::memory_order_acquire y std::memory_order_release se reemplaza por std::memory_order_relaxed.
4) Equivalente a: return compare_exchange_weak(expected, desired, order, fail_order); donde fail_order es igual que order excepto que std::memory_order_acq_rel se reemplaza por std::memory_order_acquire y std::memory_order_release se reemplaza por std::memory_order_relaxed.

atomic<shared_ptr<T>>::wait

void wait( std::shared_ptr<T> old
           std::memory_order order = std::memory_order_seq_cst ) const noexcept;

Realiza una operación de espera atómica.

Compara load(order) con old y, si son equivalentes, bloquea hasta que *this es notificado por notify_one() o notify_all(). Esto se repite hasta que cambie load(order). Se garantiza que esta función regrese solo si el valor ha cambiado, incluso si la implementación subyacente se desbloquea de forma espuria.

La memoria se ordena de acuerdo con order. El comportamiento no está definido si order es std::memory_order_release o std::memory_order_acq_rel.

Nota: dos shared_ptr son equivalentes si almacenan el mismo puntero y comparten la posesión o ambos están vacíos.

atomic<shared_ptr<T>>::notify_one

void notify_one() noexcept;

Realiza una operación de notificación atómica.

Si hay un hilo bloqueado en las operaciones de espera atómica (es decir, wait()) en *this, desbloquea al menos uno de esos hilos; de lo contrario no hace nada.

atomic<shared_ptr<T>>::notify_all

void notify_all() noexcept;

Realiza una operación de notificación atómica.

Desbloquea todos los hilos bloqueados en operaciones de espera atómica (es decir, wait()) en *this, si hay alguno; de lo contrario no hace nada.

[editar] Constantes miembro

Esta especialización también proporciona la única constante miembro estándar std::atomic is_always_lock_free.

atomic<shared_ptr<T>>::is_always_lock_free

static constexpr bool is_always_lock_free = /*definido por la implementación*/;

[editar] Notas

Macro de Prueba de característica
__cpp_lib_atomic_shared_ptr

[editar] Ejemplo

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 3661 C++20 atomic<shared_ptr<T>> no era inicializable por constante a partir de nullptr. Se hizo inicializable por constante.

[editar] Véase también

(C++11)
Plantilla de clase atómica y especializaciones para los tipos bool, enteros y tipos puntero.
(plantilla de clase) [editar]