std:: atomic_exchange, std:: atomic_exchange_explicit
|
Definiert im Header
<atomic>
|
||
|
template
<
class
T
>
T atomic_exchange
(
std::
atomic
<
T
>
*
obj,
|
(1) | (seit C++11) |
|
template
<
class
T
>
T atomic_exchange
(
volatile
std::
atomic
<
T
>
*
obj,
|
(2) | (seit C++11) |
|
template
<
class
T
>
T atomic_exchange_explicit
(
std::
atomic
<
T
>
*
obj,
|
(3) | (seit C++11) |
|
template
<
class
T
>
T atomic_exchange_explicit
(
volatile
std::
atomic
<
T
>
*
obj,
|
(4) | (seit C++11) |
Inhaltsverzeichnis |
Parameter
| obj | - | Zeiger auf das atomare Objekt, das modifiziert werden soll |
| desired | - | der Wert, der im atomaren Objekt gespeichert werden soll |
| order | - | die Speichersynchronisationsreihenfolge |
Rückgabewert
Der zuvor vom atomaren Objekt gehaltene Wert, auf das durch obj gezeigt wird.
Beispiel
Ein Spinlock-Mutex kann im Userspace mittels einer atomaren Austauschoperation implementiert werden, ähnlich wie std:: atomic_flag_test_and_set :
#include <atomic> #include <iostream> #include <thread> #include <vector> std::atomic<bool> lock(false); // holds true when locked // holds false when unlocked int new_line{1}; // the access is synchronized via atomic lock variable void f(int n) { for (int cnt = 0; cnt < 100; ++cnt) { while (std::atomic_exchange_explicit(&lock, true, std::memory_order_acquire)) ; // spin until acquired std::cout << n << (new_line++ % 80 ? "" : "\n"); std::atomic_store_explicit(&lock, false, std::memory_order_release); } } int main() { std::vector<std::thread> v; for (int n = 0; n < 8; ++n) v.emplace_back(f, n); for (auto& t : v) t.join(); }
Mögliche Ausgabe:
02222222222222222222222002222222222222222222222222222222222222222222222222222222 22222222200022222222202222211111111111110000011111111100000000000000110001111111 00011111000001111110000011111100000111000000001111111111111110000010000001001111 11011111111011111011000000000000111100000000000001111000011133333333333333333333 33333333333333333333333333333333333333333333333333333333333333333333333333333333 44444444444444444444444444444444444444444444444444444444444444444444444444444444 44444444444444444444555555555555555555555555555555555555555555555555555555555555 55555555555555555555555555555555555555556666666666666666666666666666666666666666 66666666666666666666666666666666666666666666666666666666666677777777777777777777 77777777777777777777777777777777777777777777777777777777777777777777777777777777
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, weil
T
von mehreren Argumenten abgeleitet wurde
|
T
wird nur
von obj abgeleitet |
Siehe auch
|
ersetzt atomar den Wert des atomaren Objekts und erhält den zuvor gehaltenen Wert
(öffentliche Mitgliedsfunktion von
std::atomic<T>
)
|
|
|
vergleicht atomar den Wert des atomaren Objekts mit nicht-atomarem Argument und führt atomaren Austausch bei Gleichheit oder atomares Laden bei Ungleichheit durch
(Funktionstemplate) |
|
(veraltet in C++20)
(entfernt in C++26)
|
spezialisiert atomare Operationen für
std::shared_ptr
(Funktions-Template) |
|
C-Dokumentation
für
atomic_exchange
,
atomic_exchange_explicit
|
|