std:: atomic
|
Definiert im Header
<atomic>
|
||
|
template
<
class
T
>
struct atomic ; |
(1) | (seit C++11) |
|
template
<
class
U
>
struct atomic < U * > ; |
(2) | (seit C++11) |
|
Definiert im Header
<memory>
|
||
|
template
<
class
U
>
struct atomic < std:: shared_ptr < U >> ; |
(3) | (seit C++20) |
|
template
<
class
U
>
struct atomic < std:: weak_ptr < U >> ; |
(4) | (seit C++20) |
|
Definiert im Header
<stdatomic.h>
|
||
|
#define _Atomic(T) /* siehe unten */
|
(5) | (seit C++23) |
Jede Instanziierung und vollständige Spezialisierung der
std::atomic
-Vorlage definiert einen atomaren Typ. Wenn ein Thread in ein atomares Objekt schreibt, während ein anderer Thread daraus liest, ist das Verhalten wohldefiniert (siehe
Speichermodell
für Details zu Datenrennen).
Zusätzlich können Zugriffe auf atomare Objekte Thread-synchronisation etablieren und nicht-atomare Speicherzugriffe gemäß den Vorgaben von std::memory_order anordnen.
std::atomic
ist weder kopierbar noch verschiebbar.
|
Das Kompatibilitätsmakro
Es ist nicht spezifiziert, ob Deklarationen im Namensraum
|
(seit C++23) |
Inhaltsverzeichnis |
Spezialisierungen
Primäre Vorlage
Die primäre
std::atomic
-Vorlage kann mit jedem
TriviallyCopyable
-Typ
T
instanziiert werden, der sowohl
CopyConstructible
als auch
CopyAssignable
erfüllt. Das Programm ist fehlerhaft, wenn einer der folgenden Werte
false
ist:
- 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
struct Counters { int a; int b; }; // benutzerdefinierter trivial kopierbarer Typ std::atomic<Counters> cnt; // Spezialisierung für den benutzerdefinierten Typ
std :: atomic < bool > verwendet die primäre Template-Definition. Es ist garantiert eine Standard-Layout-Struktur und besitzt einen trivialen Destruktor .
Partielle Spezialisierungen
Die Standardbibliothek bietet partielle Spezialisierungen der
std::atomic
-Vorlage für die folgenden Typen mit zusätzlichen Eigenschaften, die die primäre Vorlage nicht besitzt:
std::atomic<U*>
für alle Zeigertypen. Diese Spezialisierungen haben Standard-Layout
, triviale Standardkonstruktoren,
(bis C++20)
und triviale Destruktoren. Zusätzlich zu den Operationen, die für alle atomaren Typen bereitgestellt werden, unterstützen diese Spezialisierungen zusätzlich atomare arithmetische Operationen, die für Zeigertypen geeignet sind, wie
fetch_add
,
fetch_sub
.
|
3,4)
Partielle Spezialisierungen
std
::
atomic
<
std::
shared_ptr
<
U
>>
und
std
::
atomic
<
std::
weak_ptr
<
U
>>
werden für
std::shared_ptr
und
std::weak_ptr
bereitgestellt.
Siehe std::atomic <std::shared_ptr> und std::atomic <std::weak_ptr> für Details. |
(seit C++20) |
Spezialisierungen für Ganzzahltypen
Wenn mit einem der folgenden ganzzahligen Typen instanziiert,
stellt
std::atomic
zusätzliche atomare Operationen bereit, die für ganzzahlige Typen geeignet sind, wie z.B.
fetch_add
,
fetch_sub
,
fetch_and
,
fetch_or
,
fetch_xor
:
-
- Die Zeichentypen char , char8_t (seit C++20) , char16_t , char32_t und wchar_t ;
- Die standardmäßigen vorzeichenbehafteten Ganzzahltypen: signed char , short , int , long und long long ;
- Die standardmäßigen vorzeichenlosen Ganzzahltypen: unsigned char , unsigned short , unsigned int , unsigned long und unsigned long long ;
- Alle zusätzlichen integralen Typen, die durch die Typdefinitionen im Header <cstdint> benötigt werden.
Zusätzlich hat die resultierende
std::atomic<
Integral
>
Spezialisierung Standard-Layout
, einen trivialen Standardkonstruktor,
(bis C++20)
und einen trivialen Destruktor. Die Arithmetik für vorzeichenbehaftete Ganzzahlen ist als Zweierkomplement definiert; es gibt keine undefinierten Ergebnisse.
Spezialisierungen für Gleitkommatypen
Bei Instanziierung mit einem der cv-unqualifizierten Gleitkommatypen (
float
,
double
,
long
double
und cv-unqualifizierten
erweiterten Gleitkommatypen
(seit C++23)
),
Zusätzlich hat die resultierende
Keine Operationen führen zu undefiniertem Verhalten, selbst wenn das Ergebnis im Gleitkommatyp nicht darstellbar ist. Die aktive Gleitkommaumgebung kann sich von der Gleitkommaumgebung des aufrufenden Threads unterscheiden. |
(seit C++20) |
Mitgliedertypen
| Typ | Definition | ||||
value_type
|
T
(unabhängig davon, ob spezialisiert oder nicht)
|
||||
difference_type
[1]
|
|
-
↑
difference_typeist nicht in der primärenstd::atomic-Vorlage oder in den partiellen Spezialisierungen für std::shared_ptr und std::weak_ptr definiert.
Memberfunktionen
|
Konstruiert ein atomares Objekt
(öffentliche Elementfunktion) |
|
|
speichert einen Wert in ein atomares Objekt
(öffentliche Elementfunktion) |
|
|
prüft, ob das atomare Objekt sperrfrei ist
(öffentliche Elementfunktion) |
|
|
ersetzt atomar den Wert des atomaren Objekts mit einem nicht-atomaren Argument
(öffentliche Elementfunktion) |
|
|
liest atomar den Wert des atomaren Objekts
(öffentliche Elementfunktion) |
|
|
lädt einen Wert aus einem atomaren Objekt
(öffentliche Elementfunktion) |
|
|
ersetzt atomar den Wert des atomaren Objekts und erhält den zuvor gehaltenen Wert
(öffentliche Elementfunktion) |
|
|
vergleicht atomar den Wert des atomaren Objekts mit einem nicht-atomaren Argument und führt bei Gleichheit atomaren Austausch oder bei Ungleichheit atomare Ladung durch
(öffentliche Elementfunktion) |
|
|
(C++20)
|
blockiert den Thread, bis eine Benachrichtigung erfolgt und der atomare Wert sich ändert
(öffentliche Elementfunktion) |
|
(C++20)
|
benachrichtigt mindestens einen auf das atomare Objekt wartenden Thread
(öffentliche Elementfunktion) |
|
(C++20)
|
benachrichtigt alle auf das atomare Objekt blockiert wartenden Threads
(öffentliche Elementfunktion) |
Konstanten |
|
|
[static]
(C++17)
|
zeigt an, dass der Typ immer sperrfrei ist
(öffentliche statische Elementkonstante) |
Spezialisierte Memberfunktionen
Spezialisiert für Ganzzahl- , Gleitkomma- (seit C++20) und Zeigertypen |
|
|
addiert das Argument atomar zum im atomaren Objekt gespeicherten Wert und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
|
subtrahiert das Argument atomar vom im atomaren Objekt gespeicherten Wert und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
|
addiert zum oder subtrahiert vom atomaren Wert
(öffentliche Member-Funktion) |
|
Spezialisiert nur für Ganzzahl- und Zeigertypen |
|
|
(C++26)
|
führt atomar
std::max
zwischen dem Argument und dem Wert des atomaren Objekts aus und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
(C++26)
|
führt atomar
std::min
zwischen dem Argument und dem Wert des atomaren Objekts aus und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
erhöht oder verringert den atomaren Wert um eins
(öffentliche Member-Funktion) |
|
Spezialisiert nur für Ganzzahltypen |
|
|
führt atomar bitweises UND zwischen dem Argument und dem Wert des atomaren Objekts aus und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
|
führt atomar bitweises ODER zwischen dem Argument und dem Wert des atomaren Objekts aus und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
|
führt atomar bitweises XOR zwischen dem Argument und dem Wert des atomaren Objekts aus und erhält den zuvor gehaltenen Wert
(öffentliche Member-Funktion) |
|
|
führt bitweises UND, ODER, XOR mit dem atomaren Wert aus
(öffentliche Member-Funktion) |
|
Typaliase
Für bool und alle oben aufgeführten Ganzzahltypen werden Typaliasse bereitgestellt, wie folgt:
Aliase für alle
|
|
|
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)
(optional)
|
std
::
atomic
<
std::
int8_t
>
(typedef) |
|
atomic_uint8_t
(C++11)
(optional)
|
std
::
atomic
<
std::
uint8_t
>
(typedef) |
|
atomic_int16_t
(C++11)
(optional)
|
std
::
atomic
<
std::
int16_t
>
(typedef) |
|
atomic_uint16_t
(C++11)
(optional)
|
std
::
atomic
<
std::
uint16_t
>
(typedef) |
|
atomic_int32_t
(C++11)
(optional)
|
std
::
atomic
<
std::
int32_t
>
(typedef) |
|
atomic_uint32_t
(C++11)
(optional)
|
std
::
atomic
<
std::
uint32_t
>
(typedef) |
|
atomic_int64_t
(C++11)
(optional)
|
std
::
atomic
<
std::
int64_t
>
(typedef) |
|
atomic_uint64_t
(C++11)
(optional)
|
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)
(optional)
|
std
::
atomic
<
std::
intptr_t
>
(typedef) |
|
atomic_uintptr_t
(C++11)
(optional)
|
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) |
Aliase für spezielle Zwecktypen |
|
|
atomic_signed_lock_free
(C++20)
|
Ein vorzeichenbehafteter integraler atomarer Typ, der sperrfrei ist und für den Warten/Benachrichtigen am effizientesten ist
(typedef) |
|
atomic_unsigned_lock_free
(C++20)
|
ein vorzeichenloser integraler atomarer Typ, der sperrfrei ist und für den Warten/Benachrichtigen am effizientesten ist
(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.
|
|
(seit C++20) |
Hinweise
Es gibt nicht-Member-Funktions-Template-Äquivalente für alle Member-Funktionen von
std::atomic
. Diese nicht-Member-Funktionen können zusätzlich überladen werden für Typen, die keine Spezialisierungen von
std::atomic
sind, aber in der Lage sind, Atomarität zu garantieren. Der einzige solche Typ in der Standardbibliothek ist
std::
shared_ptr
<
U
>
.
_Atomic
ist ein
Schlüsselwort
und wird verwendet, um
atomare Typen
in C bereitzustellen.
Es wird empfohlen, dass Implementierungen sicherstellen, dass die Darstellung von
_Atomic(T)
in C dieselbe ist wie die von
std::atomic<T>
in C++ für jeden möglichen Typ
T
. Die verwendeten Mechanismen zur Sicherstellung von Atomarität und Speicherreihenfolge sollten kompatibel sein.
Bei GCC und Clang erfordert ein Teil der hier beschriebenen Funktionalität das Verlinken gegen
-latomic
.
| Feature-Test Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_atomic_ref
|
201806L
|
(C++20) |
std::atomic_ref
|
__cpp_lib_constexpr_atomic
|
202411L
|
(C++26) |
constexpr
std::atomic
und
std::atomic_ref
|
Beispiel
#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'; }
Mögliche Ausgabe:
The atomic counter is 100000 The non-atomic counter is 69696
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2441 | C++11 |
Typdefinitionen für atomare Versionen von optional
Festbreiten-Ganzzahltypen fehlten |
hinzugefügt |
| LWG 3012 | C++11 |
std::atomic<T>
war für beliebige
T
erlaubt, die trivial kopierbar aber nicht kopierbar sind |
solche Spezialisierungen sind verboten |
| LWG 3949 | C++17 |
die Formulierung, die einen trivialen Destruktor für
std
::
atomic
<
bool
>
vorschreibt, wurde in C++17 versehentlich entfernt |
wieder hinzugefügt |
|
LWG 4069
( P3323R1 ) |
C++11 |
Unterstützung für cv-qualifizierte
T
war fragwürdig
|
verbiete
T
mit CV-Qualifizierung
|
| P0558R1 | C++11 |
Template-Argumentableitung für einige
Funktionen für atomare Typen könnte versehentlich fehlschlagen; ungültige Zeigeroperationen wurden bereitgestellt |
Spezifikation wurde grundlegend überarbeitet:
Member-Typdefinitionen
value_type
und
difference_type
wurden hinzugefügt
|
Siehe auch
|
(C++11)
|
der lock-freie boolesche atomare Typ
(Klasse) |
|
(C++20)
|
atomarer Shared Pointer
(Klassen-Template-Spezialisierung) |
|
(C++20)
|
atomarer Weak Pointer
(Klassen-Template-Spezialisierung) |
|
C-Dokumentation
für
Atomare Typen
|
|