std:: atomic <std::shared_ptr>
|
Défini dans l'en-tête
<memory>
|
||
|
template
<
class
T
>
struct std:: atomic < std:: shared_ptr < T >> ; |
(depuis C++20) | |
La spécialisation partielle du modèle de
std::atomic
pour
std::
shared_ptr
<
T
>
permet aux utilisateurs de manipuler
shared_ptr
de manière atomique.
Si plusieurs threads d'exécution accèdent au même std::shared_ptr sans synchronisation et que l'un de ces accès utilise une fonction membre non constante de shared_ptr , alors une course aux données se produira, sauf si tous ces accès sont effectués via une instance de std:: atomic < std:: shared_ptr > (ou, déprécié depuis C++20, via les fonctions autonomes pour l'accès atomique à std::shared_ptr ).
Les incréments associés du
use_count
sont garantis comme faisant partie de l'opération atomique. Les décréments associés du
use_count
sont séquencés après l'opération atomique, mais ne sont pas requis d'en faire partie, sauf pour le changement du
use_count
lors du remplacement de
expected
dans un CAS échoué. Toute suppression et désallocation associées sont séquencées après l'étape de mise à jour atomique et ne font pas partie de l'opération atomique.
Notez que le bloc de contrôle d'un
shared_ptr
est thread-safe : différents objets
std::shared_ptr
non atomiques peuvent être accédés via des opérations modifiables, telles que
operator
=
ou
reset
, simultanément par plusieurs threads, même lorsque ces instances sont des copies et partagent le même bloc de contrôle en interne.
Le type T peut être un type incomplet.
Types membres
| Type de membre | Définition |
value_type
|
std:: shared_ptr < T > |
Fonctions membres
Toutes les fonctions non spécialisées de std::atomic sont également fournies par cette spécialisation, et aucune fonction membre supplémentaire n'est présente.
|
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) | |
|
void
operator
=
(
const
atomic
&
)
=
delete
;
|
(1) | |
|
void
operator
=
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(2) | |
|
void
operator
=
(
std::
nullptr_t
)
noexcept
;
|
(3) | |
|
bool
is_lock_free
(
)
const
noexcept
;
|
||
Retourne true si les opérations atomiques sur tous les objets de ce type sont sans verrou, false sinon.
|
void
store
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
Remplace atomiquement la valeur de * this par la valeur de desired comme par p. swap ( desired ) où p est le std:: shared_ptr < T > sous-jacent. La mémoire est ordonnancée selon order . Le comportement est indéfini si order est std::memory_order_consume , std::memory_order_acquire , ou std::memory_order_acq_rel .
|
std::
shared_ptr
<
T
>
load
(
std::
memory_order
order
=
std::
memory_order_seq_cst
)
const
noexcept
;
|
||
Retourne atomiquement une copie du pointeur partagé sous-jacent. La mémoire est ordonnancée selon order . Le comportement est indéfini si order est std::memory_order_release ou 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 ; |
||
Remplace atomiquement le std:: shared_ptr < T > sous-jacent par desired comme par p. swap ( desired ) où p est le std:: shared_ptr < T > sous-jacent et retourne une copie de la valeur que p avait immédiatement avant l'échange. La mémoire est ordonnancée selon order . Il s'agit d'une opération atomique de lecture-modification-écriture.
|
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) | |
use_count
de
expected
fait partie de cette opération atomique, bien que l'écriture elle-même (et toute désallocation/destruction ultérieure) ne soit pas requise de l'être.
fail_order
est identique à
order
sauf que
std::memory_order_acq_rel
est remplacé par
std::memory_order_acquire
et
std::memory_order_release
est remplacé par
std::memory_order_relaxed
.
fail_order
est identique à
order
sauf que
std::memory_order_acq_rel
est remplacé par
std::memory_order_acquire
et
std::memory_order_release
est remplacé par
std::memory_order_relaxed
.
|
void
wait
(
std::
shared_ptr
<
T
>
old,
std:: memory_order order = std:: memory_order_seq_cst ) const noexcept ; |
||
Effectue une opération d'attente atomique.
Compare
load
(
order
)
avec
old
et s'ils sont équivalents, bloque jusqu'à ce que
*
this
soit notifié par
notify_one()
ou
notify_all()
. Ceci est répété jusqu'à ce que
load
(
order
)
change. Cette fonction est garantie de ne retourner que si la valeur a changé, même si l'implémentation sous-jacente se débloque de manière sporadique.
La mémoire est ordonnée selon order . Le comportement est indéfini si order est std::memory_order_release ou std::memory_order_acq_rel .
Notes : deux
shared_ptr
sont équivalents s'ils stockent le même pointeur et soit partagent la propriété, soit sont tous deux vides.
|
void
notify_one
(
)
noexcept
;
|
||
Effectue une opération de notification atomique.
S'il existe un thread bloqué dans des opérations d'attente atomique (c'est-à-dire
wait()
) sur
*
this
, alors débloque au moins un de ces threads ; sinon ne fait rien.
|
void
notify_all
(
)
noexcept
;
|
||
Effectue une opération de notification atomique.
Débloque tous les threads bloqués dans des opérations d'attente atomique (c'est-à-dire
wait()
) sur
*
this
, s'il y en a ; sinon ne fait rien.
Constantes membres
La seule constante membre standard
std::atomic
is_always_lock_free
est également fournie par cette spécialisation.
|
static
constexpr
bool
is_always_lock_free
=
/*défini par l'implémentation*/
;
|
||
Notes
| Macro de test de fonctionnalité | Valeur | Norme | Fonctionnalité |
|---|---|---|---|
__cpp_lib_atomic_shared_ptr
|
201711L
|
(C++20) |
std::atomic<std::shared_ptr>
|
Exemple
|
Cette section est incomplète
Raison : aucun exemple |
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3661 | C++20 |
atomic<shared_ptr<T>>
n'était pas initialisable de manière constante à partir de
nullptr
|
rendu initialisable de manière constante |
| LWG 3893 | C++20 |
LWG3661
a rendu
atomic<shared_ptr<T>>
non assignable à partir de
nullptr_t
|
assignabilité restaurée |
Voir aussi
|
(C++11)
|
modèle de classe atomic et spécialisations pour bool, types entiers,
types à virgule flottante,
(depuis C++20)
et types pointeurs
(modèle de classe) |