std:: shared_mutex
|
Definiert im Header
<shared_mutex>
|
||
|
class
shared_mutex
;
|
(seit C++17) | |
Die
shared_mutex
-Klasse ist ein Synchronisationsprimitiv, das verwendet werden kann, um gemeinsame Daten vor gleichzeitigem Zugriff durch mehrere Threads zu schützen. Im Gegensatz zu anderen Mutex-Typen, die exklusiven Zugriff ermöglichen, bietet ein shared_mutex zwei Zugriffsebenen:
- shared - mehrere Threads können gemeinsamen Besitz desselben Mutex haben.
- exclusive - nur ein Thread kann den Mutex besitzen.
Wenn ein Thread den exklusiven Lock erworben hat (durch lock , try_lock ), können keine anderen Threads den Lock erwerben (einschließlich des shared ).
Wenn ein Thread den shared Lock erworben hat (durch lock_shared , try_lock_shared ), kann kein anderer Thread den exclusive Lock erwerben, aber kann den shared Lock erwerben.
Nur wenn die exklusive Sperre von keinem Thread erworben wurde, kann die gemeinsame Sperre von mehreren Threads erworben werden.
Innerhalb eines Threads kann nur eine Sperre ( shared oder exclusive ) gleichzeitig erworben werden.
Shared Mutexe sind besonders nützlich, wenn gemeinsame Daten von beliebig vielen Threads gleichzeitig sicher gelesen werden können, aber ein Thread dieselben Daten nur dann schreiben darf, wenn kein anderer Thread gleichzeitig liest oder schreibt.
Die
shared_mutex
-Klasse erfüllt alle Anforderungen von
SharedMutex
und
StandardLayoutType
.
Inhaltsverzeichnis |
Mitgliedertypen
| Mitgliedertyp | Definition |
native_handle_type
(
optional*
)
|
implementierungsdefiniert |
Memberfunktionen
|
Konstruiert den Mutex
(öffentliche Elementfunktion) |
|
|
Zerstört den Mutex
(öffentliche Elementfunktion) |
|
|
operator=
[deleted]
|
Nicht kopierzuweisbar
(öffentliche Elementfunktion) |
Exklusives Sperren |
|
|
Sperrt den Mutex, blockiert falls der Mutex nicht verfügbar ist
(öffentliche Elementfunktion) |
|
|
Versucht den Mutex zu sperren, kehrt zurück falls der Mutex nicht verfügbar ist
(öffentliche Elementfunktion) |
|
|
Entsperrt den Mutex
(öffentliche Elementfunktion) |
|
|
|
|
|
Sperrt den Mutex für gemeinsamen Besitz, blockiert falls der Mutex nicht verfügbar ist
(öffentliche Elementfunktion) |
|
|
Versucht den Mutex für gemeinsamen Besitz zu sperren, kehrt zurück falls der Mutex nicht verfügbar ist
(öffentliche Elementfunktion) |
|
|
Entsperrt den Mutex (gemeinsamer Besitz)
(öffentliche Elementfunktion) |
|
Systemeigenes Handle |
|
|
Gibt das zugrundeliegende implementierungsdefinierte systemeigene Handle-Objekt zurück
(öffentliche Elementfunktion) |
|
Beispiel
Die folgende Ausgabe wurde auf einem Single-Core-System erzeugt. Wenn
thread1
startet, tritt es zum ersten Mal in die Schleife ein und ruft
increment()
gefolgt von
get()
auf. Bevor es jedoch den zurückgegebenen Wert an
std::
cout
ausgeben kann, setzt der Scheduler
thread1
schlafen und weckt
thread2
, welches offensichtlich genug Zeit hat, um alle drei Schleifendurchläufe auf einmal auszuführen. Zurück zu
thread1
, immer noch im ersten Schleifendurchlauf, gibt es schließlich seine lokale Kopie des Zählerwerts, der
1
beträgt, an
std::cout
aus und führt dann die verbleibenden zwei Schleifendurchläufe aus. Auf einem Multi-Core-System wird keiner der Threads schlafen gesetzt und die Ausgabe ist wahrscheinlicher in aufsteigender Reihenfolge.
#include <iostream> #include <mutex> #include <shared_mutex> #include <syncstream> #include <thread> class ThreadSafeCounter { public: ThreadSafeCounter() = default; // Multiple threads/readers can read the counter's value at the same time. unsigned int get() const { std::shared_lock lock(mutex_); return value_; } // Only one thread/writer can increment/write the counter's value. void increment() { std::unique_lock lock(mutex_); ++value_; } // Only one thread/writer can reset/write the counter's value. void reset() { std::unique_lock lock(mutex_); value_ = 0; } private: mutable std::shared_mutex mutex_; unsigned int value_{}; }; int main() { ThreadSafeCounter counter; auto increment_and_print = [&counter]() { for (int i{}; i != 3; ++i) { counter.increment(); std::osyncstream(std::cout) << std::this_thread::get_id() << ' ' << counter.get() << '\n'; } }; std::thread thread1(increment_and_print); std::thread thread2(increment_and_print); thread1.join(); thread2.join(); }
Mögliche Ausgabe:
123084176803584 2 123084176803584 3 123084176803584 4 123084185655040 1 123084185655040 5 123084185655040 6
Siehe auch
|
(C++14)
|
bietet gemeinsame gegenseitige Ausschlusseinrichtung und implementiert Sperren mit Timeout
(Klasse) |
|
(C++14)
|
implementiert beweglichen Shared-Mutex-Eigentums-Wrapper
(Klassentemplate) |
|
(C++11)
|
implementiert beweglichen Mutex-Eigentums-Wrapper
(Klassentemplate) |