Namespaces
Variants

std:: atomic

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
atomic
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
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 _Atomic wird in <stdatomic.h> bereitgestellt, sodass _Atomic(T) identisch zu std::atomic<T> ist, solange beide wohlgeformt sind.

Es ist nicht spezifiziert, ob Deklarationen im Namensraum std verfügbar sind, wenn <stdatomic.h> eingebunden wird.

(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:

**Anmerkung:** Da der gesamte Inhalt innerhalb von ` ` Tags liegt (was als Code-ähnliche Formatierung behandelt wird) und es sich um C++-spezifische Begriffe handelt, wurde gemäß den Anforderungen kein Text übersetzt.
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:

2) Partielle Spezialisierungen 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) ), std::atomic bietet zusätzliche atomare Operationen für Gleitkommatypen wie fetch_add und fetch_sub .

Zusätzlich hat die resultierende std::atomic< Floating > Spezialisierung Standard-Layout und einen trivialen Destruktor.

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]

value_type (nur für atomic< Integral > und atomic< Floating > (seit C++20) Spezialisierungen)

std::ptrdiff_t (nur für std::atomic<U*> Spezialisierungen)

  1. difference_type ist nicht in der primären std::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 std::atomic<Integral>
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)
Note: 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.

std::atomic_signed_lock_free und std::atomic_unsigned_lock_free sind in freistehenden Implementierungen optional.

(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

der lock-freie boolesche atomare Typ
(Klasse)
atomarer Shared Pointer
(Klassen-Template-Spezialisierung)
atomarer Weak Pointer
(Klassen-Template-Spezialisierung)
C-Dokumentation für Atomare Typen