Klassen:
- Klasse
std::atomic_flag - Klasse
std::atomic<> - Klasse
std::mutex
Aufzählungstypen:
- Aufzählungstyp
enum class memory_order
Konstanten:
std::memory_order_relaxedstd::memory_order_consumestd::memory_order_acquirestd::memory_order_releasestd::memory_order_acq_relstd::memory_order_seq_cst
Wenn ein Thread versucht, ein Mutex-Objekt zu sperren (Aufruf von lock) und das Mutex-Objekt bereits gesperrt ist,
wird der aktuelle Thread in einen Ruhezustand versetzt (suspend),
sodass ein anderer Thread ausgeführt werden kann (resume).
Der Zustand des suspendierten Threads ändert sich nur, wenn dieser Thread aufgeweckt wird,
und dies geschieht nur, wenn das Mutex-Objekt von dem Thread entsperrt wird, der die Sperre verursacht hat (Aufruf von unlock).
Wenn ein Thread hingegen ein Spinlock-Objekt sperrt und dies fehlschlägt, versucht er kontinuierlich erneut, dieses zu sperren, bis das Vorhaben gelingt.
Es kommt also nicht zu einem Thread-Wechsel!
Natürlich gibt es hier eine Ausnahme: Das Betriebssystem wechselt dann zu einem anderen Thread, wenn das CPU-Laufzeitkontingent des aktuellen Threads überschritten wurde.
Bewirkt ein Mutex-Objekt einen Zustandswechsel eines Threads in den Ruhezustand, zieht dies einen Kontextwechsel auf Betriebssystemebene nach sich, der zu Leistungseinbußen führt.
Wenn Sie diese Einbußen vermeiden und eine kurze Sperrzeit haben möchten, ist der Einsatz eines Spinlock-Objekts möglicherweise eine gute Alternative.
In diesem Abschnitt demonstrieren wir die Implementierung einer Spinlock-Klasse.
Die Ideen zu den Beispielen aus diesem Abschnitt stammen aus diesen Artikeln:
Implementing a spinlock in C++.
Spin lock in Modern C++ with atomics, memory barriers and exponential back-off.
Correctly implementing a spinlock in C++.