Namespaces
Variants

std:: atomic_fetch_add, std:: atomic_fetch_add_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_fetch_add atomic_fetch_add_explicit
(C++11) (C++11)
Free functions for atomic flags
Definiert im Header <atomic>
template < class T >

T atomic_fetch_add ( std:: atomic < T > * obj,

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

T atomic_fetch_add ( volatile std:: atomic < T > * obj,

typename std:: atomic < T > :: difference_type arg ) noexcept ;
(2) (seit C++11)
template < class T >

T atomic_fetch_add_explicit ( std:: atomic < T > * obj,
typename std:: atomic < T > :: difference_type arg,

std:: memory_order order ) noexcept ;
(3) (seit C++11)
template < class T >

T atomic_fetch_add_explicit ( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: difference_type arg,

std:: memory_order order ) noexcept ;
(4) (seit C++11)

Führt eine atomare Addition durch. Addiert atomar arg zu dem Wert, auf den obj zeigt, und gibt den Wert zurück, der zuvor in obj gespeichert war. Die Operation wird so ausgeführt, als ob Folgendes ausgeführt würde:

1,2) obj - > fetch_add ( arg )
3,4) obj - > fetch_add ( arg, order )

Wenn std::atomic<T> kein fetch_add Mitglied hat (dieses Mitglied wird nur für integrale , Gleitkomma- (seit C++20) und Zeiger Typen außer bool bereitgestellt), ist das Programm fehlerhaft.

Inhaltsverzeichnis

Parameter

obj - Zeiger auf das atomare Objekt, das modifiziert werden soll
arg - der Wert, der zum im atomaren Objekt gespeicherten Wert addiert werden soll
order - die Speichersynchronisierungsreihenfolge

Rückgabewert

Der Wert unmittelbar vor den Auswirkungen dieser Funktion in der modification order von * obj .

Beispiel

Ein Single-Writer/Multiple-Reader-Lock kann mit std::atomic_fetch_add implementiert werden. Beachten Sie, dass diese einfache Implementierung nicht sperrfrei ist.

#include <atomic>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>
using namespace std::chrono_literals;
// Bedeutung von cnt:
//  5: Leser und Writer im Wettlauf. Keine aktiven Leser oder Writer.
//  4...0: Es gibt 1...5 aktive Leser. Der Writer ist blockiert.
// -1: Writer hat den Wettlauf gewonnen und Leser sind blockiert.
const int N = 5; // Vier parallele Leser sind erlaubt
std::atomic<int> cnt(N);
std::vector<int> data;
void reader(int id)
{
    for (;;)
    {
        // Sperren
        while (std::atomic_fetch_sub(&cnt, 1) <= 0)
            std::atomic_fetch_add(&cnt, 1);
        // Lesen
        if (!data.empty())
            std::cout << ("reader " + std::to_string(id) +
                          " sees " + std::to_string(*data.rbegin()) + '\n');
        if (data.size() == 25)
            break;
        // Entsperren
        std::atomic_fetch_add(&cnt, 1);
        // Pause
        std::this_thread::sleep_for(1ms);
    }
}
void writer()
{
    for (int n = 0; n < 25; ++n)
    {
        // Sperren
        while (std::atomic_fetch_sub(&cnt, N + 1) != N)
            std::atomic_fetch_add(&cnt, N + 1);
        // Schreiben
        data.push_back(n);
        std::cout << "writer pushed back " << n << '\n';
        // Entsperren
        std::atomic_fetch_add(&cnt, N + 1);
        // Pause
        std::this_thread::sleep_for(1ms);
    }
}
int main()
{
    std::vector<std::thread> v;
    for (int n = 0; n < N; ++n)
        v.emplace_back(reader, n);
    v.emplace_back(writer);
    for (auto& t : v)
        t.join();
}

Ausgabe:

writer pushed back 0
reader 2 sees 0
reader 3 sees 0
reader 1 sees 0
<...>
reader 2 sees 24
reader 4 sees 24
reader 1 sees 24

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

addiert atomar das Argument zum im atomaren Objekt gespeicherten Wert und erhält den zuvor gehaltenen Wert
(öffentliche Mitgliedsfunktion von std::atomic<T> )
subtrahiert einen nicht-atomaren Wert von einem atomaren Objekt und erhält den vorherigen Wert des atomaren Objekts
(Funktions-Template)
C-Dokumentation für atomic_fetch_add , atomic_fetch_add_explicit