std:: atomic
|
Défini dans l'en-tête
<atomic>
|
||
|
template
<
class
T
>
struct atomic ; |
(1) | (depuis C++11) |
|
template
<
class
U
>
struct atomic < U * > ; |
(2) | (depuis C++11) |
|
Défini dans l'en-tête
<memory>
|
||
|
template
<
class
U
>
struct atomic < std:: shared_ptr < U >> ; |
(3) | (depuis C++20) |
|
template
<
class
U
>
struct atomic < std:: weak_ptr < U >> ; |
(4) | (depuis C++20) |
|
Défini dans l'en-tête
<stdatomic.h>
|
||
|
#define _Atomic(T) /* voir ci-dessous */
|
(5) | (depuis C++23) |
Chaque instanciation et spécialisation complète du modèle
std::atomic
définit un type atomique. Si un thread écrit dans un objet atomique pendant qu'un autre thread le lit, le comportement est bien défini (voir le
modèle de mémoire
pour plus de détails sur les courses de données).
De plus, les accès aux objets atomiques peuvent établir une synchronisation inter-threads et ordonner les accès mémoire non atomiques comme spécifié par std::memory_order .
std::atomic
n'est ni copiable ni déplaçable.
|
La macro de compatibilité
Il n'est pas spécifié si une déclaration dans l'espace de noms
|
(depuis C++23) |
Table des matières |
Spécialisations
Modèle principal
Le modèle principal
std::atomic
peut être instancié avec tout type
TriviallyCopyable
T
satisfaisant à la fois
CopyConstructible
et
CopyAssignable
. Le programme est mal formé si l'une des valeurs suivantes est
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
` tags), no translation was performed as per the instructions. The structure and formatting remain completely unchanged.*
struct Counters { int a; int b; }; // type défini par l'utilisateur trivialement copiable std::atomic<Counters> cnt; // spécialisation pour le type défini par l'utilisateur
std :: atomic < bool > utilise le modèle principal. Il est garanti d'être une structure de disposition standard et possède un destructeur trivial .
Spécialisations partielles
La bibliothèque standard fournit des spécialisations partielles du modèle
std::atomic
pour les types suivants avec des propriétés supplémentaires que le modèle principal ne possède pas :
std::atomic<U*>
pour tous les types pointeurs. Ces spécialisations ont une disposition standard
, des constructeurs par défaut triviaux,
(jusqu'à C++20)
et des destructeurs triviaux. En plus des opérations fournies pour tous les types atomiques, ces spécialisations supportent également des opérations arithmétiques atomiques appropriées aux types pointeurs, telles que
fetch_add
,
fetch_sub
.
|
3,4)
Spécialisations partielles
std
::
atomic
<
std::
shared_ptr
<
U
>>
et
std
::
atomic
<
std::
weak_ptr
<
U
>>
sont fournies pour
std::shared_ptr
et
std::weak_ptr
.
Voir std::atomic <std::shared_ptr> et std::atomic <std::weak_ptr> pour plus de détails. |
(depuis C++20) |
Spécialisations pour les types entiers
Lorsqu'il est instancié avec l'un des types entiers suivants,
std::atomic
fournit des opérations atomiques supplémentaires appropriées aux types entiers telles que
fetch_add
,
fetch_sub
,
fetch_and
,
fetch_or
,
fetch_xor
:
-
- Les types de caractères char , char8_t (depuis C++20) , char16_t , char32_t , et wchar_t ;
- Les types entiers signés standards : signed char , short , int , long , et long long ;
- Les types entiers non signés standards : unsigned char , unsigned short , unsigned int , unsigned long , et unsigned long long ;
- Tout type entier supplémentaire requis par les typedefs dans l'en-tête <cstdint> .
De plus, la spécialisation résultante
std::atomic<
Integral
>
a une disposition standard
, un constructeur par défaut trivial,
(jusqu'à C++20)
et un destructeur trivial. L'arithmétique des entiers signés est définie pour utiliser le complément à deux ; il n'y a pas de résultats indéfinis.
Spécialisations pour les types à virgule flottante
Lorsqu'instancié avec l'un des types à virgule flottante non qualifiés cv (
float
,
double
,
long
double
et les types à virgule flottante étendus non qualifiés cv
extended floating-point types
(depuis C++23)
),
De plus, la spécialisation résultante
Aucune opération ne résulte en un comportement indéfini même si le résultat n'est pas représentable dans le type à virgule flottante. L'environnement floating-point environment en vigueur peut être différent de l'environnement à virgule flottante du thread appelant. |
(depuis C++20) |
Types membres
| Type | Définition | ||||
value_type
|
T
(indépendamment de la spécialisation)
|
||||
difference_type
[1]
|
|
-
↑
difference_typen'est pas défini dans le modèle principalstd::atomicou dans les spécialisations partielles pour std::shared_ptr et std::weak_ptr .
Fonctions membres
|
construit un objet atomique
(fonction membre publique) |
|
|
stocke une valeur dans un objet atomique
(fonction membre publique) |
|
|
vérifie si l'objet atomique est sans verrou
(fonction membre publique) |
|
|
remplace atomiquement la valeur de l'objet atomique par un argument non atomique
(fonction membre publique) |
|
|
obtient atomiquement la valeur de l'objet atomique
(fonction membre publique) |
|
|
charge une valeur depuis un objet atomique
(fonction membre publique) |
|
|
remplace atomiquement la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
compare atomiquement la valeur de l'objet atomique avec un argument non atomique et effectue un échange atomique si égal ou un chargement atomique sinon
(fonction membre publique) |
|
|
(C++20)
|
bloque le thread jusqu'à notification et changement de la valeur atomique
(fonction membre publique) |
|
(C++20)
|
notifie au moins un thread en attente sur l'objet atomique
(fonction membre publique) |
|
(C++20)
|
notifie tous les threads bloqués en attente sur l'objet atomique
(fonction membre publique) |
Constantes |
|
|
[static]
(C++17)
|
indique que le type est toujours sans verrou
(constante membre statique publique) |
Fonctions membres spécialisées
Spécialisé pour les types entiers , virgule flottante (depuis C++20) et pointeurs |
|
|
ajoute atomiquement l'argument à la valeur stockée dans l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
soustrait atomiquement l'argument de la valeur stockée dans l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
ajoute ou soustrait de la valeur atomique
(fonction membre publique) |
|
Spécialisé uniquement pour les types entiers et pointeurs |
|
|
(C++26)
|
effectue atomiquement
std::max
entre l'argument et la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
(C++26)
|
effectue atomiquement
std::min
entre l'argument et la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
incrémente ou décrémente la valeur atomique de un
(fonction membre publique) |
|
Spécialisé uniquement pour les types entiers |
|
|
effectue atomiquement un ET bit à bit entre l'argument et la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
effectue atomiquement un OU bit à bit entre l'argument et la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
effectue atomiquement un XOR bit à bit entre l'argument et la valeur de l'objet atomique et obtient la valeur précédemment détenue
(fonction membre publique) |
|
|
effectue un ET, OU, XOR bit à bit avec la valeur atomique
(fonction membre publique) |
|
Alias de types
Des alias de type sont fournis pour bool et tous les types entiers listés ci-dessus, comme suit :
Alias pour tous les
|
|
|
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)
(optionnel)
|
std
::
atomic
<
std::
int8_t
>
(typedef) |
|
atomic_uint8_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
uint8_t
>
(typedef) |
|
atomic_int16_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
int16_t
>
(typedef) |
|
atomic_uint16_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
uint16_t
>
(typedef) |
|
atomic_int32_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
int32_t
>
(typedef) |
|
atomic_uint32_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
uint32_t
>
(typedef) |
|
atomic_int64_t
(C++11)
(optionnel)
|
std
::
atomic
<
std::
int64_t
>
(typedef) |
|
atomic_uint64_t
(C++11)
(optionnel)
|
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)
(optionnel)
|
std
::
atomic
<
std::
intptr_t
>
(typedef) |
|
atomic_uintptr_t
(C++11)
(optionnel)
|
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 pour les types à usage spécifique |
|
|
atomic_signed_lock_free
(C++20)
|
un type atomique entier signé sans verrouillage pour lequel l'attente/la notification est la plus efficace
(typedef) |
|
atomic_unsigned_lock_free
(C++20)
|
un type atomique entier non signé sans verrouillage pour lequel l'attente/la notification est la plus efficace
(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.
|
|
(depuis C++20) |
Notes
Il existe des équivalents de modèles de fonctions non membres pour toutes les fonctions membres de
std::atomic
. Ces fonctions non membres peuvent être en outre surchargées pour des types qui ne sont pas des spécialisations de
std::atomic
, mais sont capables de garantir l'atomicité. Le seul type de ce genre dans la bibliothèque standard est
std::
shared_ptr
<
U
>
.
_Atomic
est un
mot-clé
et est utilisé pour fournir les
types atomiques
en C.
Il est recommandé que les implémentations garantissent que la représentation de
_Atomic(T)
en C soit identique à celle de
std::atomic<T>
en C++ pour tout type
T
possible. Les mécanismes utilisés pour assurer l'atomicité et l'ordonnancement de la mémoire devraient être compatibles.
Sur GCC et Clang, certaines fonctionnalités décrites ici nécessitent une liaison avec
-latomic
.
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_atomic_ref
|
201806L
|
(C++20) |
std::atomic_ref
|
__cpp_lib_constexpr_atomic
|
202411L
|
(C++26) |
constexpr
std::atomic
et
std::atomic_ref
|
Exemple
#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'; }
Sortie possible :
The atomic counter is 100000 The non-atomic counter is 69696
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 | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 2441 | C++11 |
les typedefs pour les versions atomiques des types entiers
à largeur fixe optionnels manquaient |
ajoutés |
| LWG 3012 | C++11 |
std::atomic<T>
était autorisé pour tout
T
trivialement copiable mais non copiable |
ces spécialisations sont interdites |
| LWG 3949 | C++17 |
la formulation exigeant que
std
::
atomic
<
bool
>
ait un
destructeur trivial a été accidentellement supprimée en C++17 |
rétablie |
|
LWG 4069
( P3323R1 ) |
C++11 |
le support pour
T
qualifié cv était discutable
|
interdire que
T
soit qualifié cv
|
| P0558R1 | C++11 |
la déduction d'arguments template pour certaines
fonctions de types atomiques pouvait échouer accidentellement ; des opérations de pointeur invalides étaient fournies |
la spécification a été substantiellement réécrite :
les typedefs membres
value_type
et
difference_type
sont ajoutés
|
Voir aussi
|
(C++11)
|
le type atomique booléen sans verrouillage
(classe) |
|
(C++20)
|
pointeur partagé atomique
(spécialisation de modèle de classe) |
|
(C++20)
|
pointeur faible atomique
(spécialisation de modèle de classe) |
|
Documentation C
pour
Types atomiques
|
|