std::atomic<std::shared_ptr>
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.
[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.
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) | |
desired
. Como con cualquier tipo std::atomic, la inicialización no es una operación atómica. void operator=( const atomic& ) = delete; |
(1) | |
void operator=( std::shared_ptr<T> desired ) noexcept; |
(2) | |
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.
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.
std::shared_ptr<T> load( std::memory_order order = std::memory_order_seq_cst ) const noexcept; |
||
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.
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.
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) | |
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.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.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.
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.
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.
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
.
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
Esta sección está incompleta Razón: sin 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) |