std::atomic_ref<T>::atomic_ref
Von cppreference.com
< cpp | atomic | atomic ref
explicit atomic_ref( T& obj ); |
(1) | (constexpr seit C++26) |
atomic_ref( const atomic_ref& ref ) noexcept; |
(2) | (constexpr seit C++26) |
Konstruiert ein neues atomic_ref-Objekt.
1) Konstruiert ein
atomic_ref-Objekt, das auf das Objekt obj verweist. Wenn obj nicht an
required_alignment ausgerichtet ist, ist das Verhalten undefiniert.2) Konstruiert ein
atomic_ref-Objekt, das auf das Objekt verweist, auf das von ref verwiesen wird.[edit] Parameter
| obj | - | Das zu referenzierende Objekt |
| ref | - | Ein weiteres atomic_ref-Objekt, von dem kopiert werden soll |
[edit] Beispiel
Das Programm inkrementiert die Werte in einem Container mithilfe mehrerer Threads. Anschließend wird die endgültige Summe ausgegeben. Ein nicht-atomarer Zugriff kann aufgrund von Datenrennen zu "Verlusten" einiger Operationen führen.
Führen Sie diesen Code aus
#include <atomic> #include <iostream> #include <numeric> #include <thread> #include <vector> int main() { using Data = std::vector<char>; auto inc_atomically = [](Data& data) { for (Data::value_type& x : data) { auto xx = std::atomic_ref<Data::value_type>(x); ++xx; // atomic read-modify-write } }; auto inc_directly = [](Data& data) { for (Data::value_type& x : data) ++x; }; auto test_run = [](const auto Fun) { Data data(10'000'000); { std::jthread j1{Fun, std::ref(data)}; std::jthread j2{Fun, std::ref(data)}; std::jthread j3{Fun, std::ref(data)}; std::jthread j4{Fun, std::ref(data)}; } std::cout << "sum = " << std::accumulate(cbegin(data), cend(data), 0) << '\n'; }; test_run(inc_atomically); test_run(inc_directly); }
Mögliche Ausgabe
sum = 40000000 sum = 39994973