C++-Standardbibliothek<atomic>

In der Multithread-Programmierung sind Datensynchronisation und Thread-Sicherheit wichtige Themen.

Der C++11-Standard führte ein<atomic>Die Bibliothek stellt eine Reihe atomarer Operationen bereit, um sicherzustellen, dass der Zugriff auf ein einzelnes Datenelement in einer Multithread-Umgebung atomar, d. h. unteilbar, ist. Dies kann Datenrennen vermeiden und die Thread-Sicherheit gewährleisten.

Atomare Operationen sind Operationen, die während der Ausführung nicht von anderen Threads unterbrochen werden können.

<atomic>Die atomaren Typen in der Bibliothek bieten solche Operationen, die einen sicheren Zugriff auf gemeinsam genutzte Daten in einer Multithread-Umgebung gewährleisten können.

Syntax

<atomic>Die Bibliothek stellt verschiedene atomare Typen bereit, darunteratomic<bool>, atomic<char>, atomic<short>, atomic<int>, atomic<long>, atomic<long long>, atomic<wchar_t>, atomic<char16_t>, atomic<char32_t>, atomic<unsigned char>, atomic<unsigned short>, atomic<unsigned>, atomic<unsigned long>, atomic<unsigned long long>, atomic<float>, atomic<double>, atomic<long double>usw.

Grundlegende Operationen

  • load(): den Wert einer atomaren Variablen sicher lesen.
  • store(value): einen Wert sicher in eine atomare Variable schreiben.
  • exchange(value): den Wert einer atomaren Variable ersetzen durchvalue, und den alten Wert der atomaren Variable zurückgeben.
  • compare_exchange_weak(expected, desired): wenn der aktuelle Wert der atomaren Variable gleichexpected, dann setze ihn aufdesired, und gibt zurücktrue. Andernfalls wird sieexpectedAuf den aktuellen Wert der atomaren Variable setzen und zurückgeben.false。
  • compare_exchange_strong(expected, desired): undcompare_exchange_weakähnlich, aber wiederholt den Vorgang, bis er erfolgreich ist.

Beispiel

Das Folgende ist ein Beispiel unter Verwendung von<atomic>Ein einfaches Beispiel für die Bibliothek, das zeigt, wie ein gemeinsamer Zähler in einer Multithread-Umgebung sicher aktualisiert wird.

Beispiel

#include <iostream>
#include <atomic>
#include <thread>

std::atomic<int> counter(0); // Atomaren Zähler initialisieren

void increment() {
    for (int i = 0; i < 10000; ++i) {
        counter.fetch_add(1, std::memory_order_relaxed); // Atomare Inkrementierung
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Endgültiger Zählerwert: " << counter << std::endl; // Den endgültigen Zählerwert ausgeben

    return 0;
}

Wenn Sie das obige Programm ausführen, sehen Sie eine Ausgabe ähnlich wie:

Final counter value: 20000

Diese Ausgabe zeigt, dass die beiden Threads den Zählerwert jeweils 10000 Mal erfolgreich ohne Datenrennen inkrementiert haben.

Hinweise

  • Nutzung<atomic>Bei der Verwendung der Bibliothek muss sichergestellt werden, dass alle Zugriffe auf gemeinsam genutzte Daten über atomare Operationen erfolgen, um Datenrennen zu vermeiden.
  • Verschiedene atomare Operationen haben unterschiedliche Anforderungen an die Speicherreihenfolge.std::memory_order_relaxedEs ist die niedrigste Anforderung an die Speicherreihenfolge, aber sie garantiert möglicherweise nicht die Sichtbarkeit von Operationen. Wählen Sie je nach Bedarf eine geeignete Speicherreihenfolge.
  • Der Performance-Overhead atomarer Operationen ist normalerweise höher als der von nicht-atomaren Operationen, daher kann in einer Single-Threaded-Umgebung die Verwendung gewöhnlicher Variablen effizienter sein.

durch die Verwendung von<atomic>Mit der Bibliothek können C++-Programmierer einfacher threadsicheren Code schreiben und dabei hohe Leistung beibehalten.

Weitere Erweiterungen