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 <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.