Namespaces
Variants

std:: atomic_compare_exchange_weak, std:: atomic_compare_exchange_strong, std:: atomic_compare_exchange_weak_explicit, std:: atomic_compare_exchange_strong_explicit

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
(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
atomic_compare_exchange_weak atomic_compare_exchange_weak_explicit atomic_compare_exchange_strong atomic_compare_exchange_strong_explicit
(C++11) (C++11) (C++11) (C++11)
Free functions for atomic flags
(Anmerkung: Der bereitgestellte HTML-Code enthält keinen übersetzbaren Text, da alle Tags leer sind. Die Struktur bleibt unverändert, wie angefordert.)
Definiert im Header <atomic>
template < class T >

bool atomic_compare_exchange_weak
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(1) (seit C++11)
template < class T >

bool atomic_compare_exchange_weak
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * erwartet,

typename std:: atomic < T > :: value_type gewünscht ) noexcept ;
(2) (seit C++11)
template < class T >

bool atomic_compare_exchange_strong
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(3) (seit C++11)
template < class T >

bool atomic_compare_exchange_strong
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * erwartet,

typename std:: atomic < T > :: value_type gewünscht ) noexcept ;
(4) (seit C++11)
template < class T >

bool atomic_compare_exchange_weak_explicit
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(5) (seit C++11)
template < class T >

bool atomic_compare_exchange_weak_explicit
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(6) (seit C++11)
template < class T >

bool atomic_compare_exchange_strong_explicit
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(7) (seit C++11)
template < class T >

bool atomic_compare_exchange_strong_explicit
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(8) (seit C++11)

Vergleicht atomar die Objektrepräsentation (bis C++20) Wertrepräsentation (seit C++20) des Objekts, auf das obj zeigt, mit der des Objekts, auf das expected zeigt, und ersetzt erstere durch desired , falls diese bitweise gleich sind (führt Lese-Modifizier-Schreib-Operation durch). Andernfalls lädt es den tatsächlichen Wert, auf den obj zeigt, in * expected (führt Ladeoperation durch).

Überladungen Speichermodell für
Lese‑Modifizieren‑Schreiben‑Operation Ladeoperation
(1-4) std:: memory_order_seq_cst std:: memory_order_seq_cst
(5-8) success failure

Diese Funktionen sind definiert in Bezug auf Member-Funktionen von std::atomic :

1,2) obj - > compare_exchange_weak ( * expected, desired )
3,4) obj - > compare_exchange_strong ( * expected, desired )
5,6) obj - > compare_exchange_weak ( * expected, desired, success, failure )
7,8) obj - > compare_exchange_strong ( * expected, desired, success, failure )

Wenn failure stärker als success ist oder (bis C++17) einer der Werte std:: memory_order_release und std:: memory_order_acq_rel ist, ist das Verhalten undefiniert.

Inhaltsverzeichnis

Parameter

obj - Zeiger auf das atomare Objekt, das getestet und modifiziert werden soll
expected - Zeiger auf den Wert, der voraussichtlich im atomaren Objekt gefunden wird
desired - der Wert, der im atomaren Objekt gespeichert werden soll, falls es den Erwartungen entspricht
success - die Speichersynchronisationsreihenfolge für den Lese-Modifizier-Schreib-Vorgang bei erfolgreichem Vergleich
failure - die Speichersynchronisationsreihenfolge für den Ladevorgang bei fehlgeschlagenem Vergleich

Rückgabewert

Das Ergebnis des Vergleichs: true wenn * obj gleich * expected war, false andernfalls.

Hinweise

std::atomic_compare_exchange_weak und std::atomic_compare_exchange_weak_explicit (die schwachen Versionen) dürfen sporadisch fehlschlagen, das heißt, sich so verhalten, als ob * obj ! = * expected selbst wenn sie gleich sind. Wenn sich ein Compare-and-Exchange in einer Schleife befindet, erzielen sie auf einigen Plattformen eine bessere Leistung.

Wenn ein schwacher Vergleichs- und Austauschvorgang eine Schleife erfordern würde und ein starker nicht, ist der starke vorzuziehen, es sei denn, die Objektdarstellung von T kann Padding-Bits, (bis C++20) Trap-Bits oder mehrere Objektdarstellungen für denselben Wert enthalten (z.B. Gleitkomma-NaN). In diesen Fällen funktioniert der schwache Vergleichs- und Austauschvorgang typischerweise, da er schnell auf eine stabile Objektdarstellung konvergiert.

Für eine Union mit Bits, die an den Wertdarstellungen einiger Mitglieder teilnehmen, aber nicht an anderen, könnte Compare-and-Exchange immer fehlschlagen, da solche Padding-Bits unbestimmte Werte haben, wenn sie nicht an der Wertdarstellung des aktiven Mitglieds teilnehmen.

Padding-Bits, die niemals an der Wertdarstellung eines Objekts teilnehmen, werden ignoriert.

(since C++20)

Beispiel

Compare-and-Exchange-Operationen werden häufig als grundlegende Bausteine von lockfreien Datenstrukturen verwendet.

#include <atomic>
template<class T>
struct node
{
    T data;
    node* next;
    node(const T& data) : data(data), next(nullptr) {}
};
template<class T>
class stack
{
    std::atomic<node<T>*> head;
public:
    void push(const T& data)
    {
        node<T>* new_node = new node<T>(data);
        // put the current value of head into new_node->next
        new_node->next = head.load(std::memory_order_relaxed);
        // now make new_node the new head, but if the head
        // is no longer what's stored in new_node->next
        // (some other thread must have inserted a node just now)
        // then put that new head into new_node->next and try again
        while (!std::atomic_compare_exchange_weak_explicit(
                   &head, &new_node->next, new_node,
                   std::memory_order_release, std::memory_order_relaxed))
            ; // the body of the loop is empty
// note: the above loop is not thread-safe in at least
// GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
// MSVC prior to 2014-03-17 (bug 819819). See member function version for workaround
    }
};
int main()
{
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
}

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
P0558R1 C++11 exakte Typübereinstimmung war erforderlich, da
T von mehreren Argumenten abgeleitet wurde
T wird nur von
obj abgeleitet

Siehe auch

vergleicht atomar den Wert des atomaren Objekts mit nicht-atomarem Argument und führt atomaren Austausch durch wenn gleich oder atomares Laden wenn nicht gleich
(öffentliche Mitgliedsfunktion von std::atomic<T> )
ersetzt atomar den Wert des atomaren Objekts mit nicht-atomarem Argument und gibt den alten Wert des atomaren Objekts zurück
(Funktionstemplate)
spezialisiert atomare Operationen für std::shared_ptr
(Funktions-Template)
C-Dokumentation für atomic_compare_exchange , atomic_compare_exchange_explicit