std::shared_mutex::lock_shared
| void lock_shared(); |
(seit C++17) | |
Erwirbt den gemeinsamen Besitz des Mutex. Wenn ein anderer Thread den Mutex exklusiv besitzt, blockiert ein Aufruf von lock_shared die Ausführung, bis gemeinsamer Besitz erworben werden kann.
Wenn lock_shared von einem Thread aufgerufen wird, der den mutex bereits in irgendeinem Modus (exklusiv oder gemeinsam) besitzt, ist das Verhalten undefiniert.
Wenn mehr als die implementierungsdefinierte maximale Anzahl von gemeinsamen Besitzern den Mutex bereits im gemeinsamen Modus gesperrt hat, blockiert lock_shared die Ausführung, bis die Anzahl der gemeinsamen Besitzer reduziert ist. Die maximale Anzahl von Besitzern ist garantiert mindestens 10000.
Eine vorherige unlock()-Operation auf demselben Mutex synchronisiert mit (wie in std::memory_order definiert) dieser Operation.
Inhalt |
[bearbeiten] Parameter
(keine)
[bearbeiten] Rückgabewert
(keine)
[bearbeiten] Ausnahmen
Wirft std::system_error bei Fehlern, einschließlich Fehlern des zugrunde liegenden Betriebssystems, die verhindern, dass lock seine Spezifikationen erfüllt. Die Mutex ist im Falle einer geworfenen Ausnahme nicht gesperrt.
[bearbeiten] Hinweise
lock_shared() wird normalerweise nicht direkt aufgerufen: std::shared_lock wird zur Verwaltung der gemeinsamen Sperrung verwendet.
[bearbeiten] Beispiel
#include <chrono> #include <iostream> #include <mutex> #include <shared_mutex> #include <syncstream> #include <thread> #include <vector> std::mutex stream_mutx; void print(auto v) { std::unique_lock<std::mutex> lock(stream_mutx); std::cout << std::this_thread::get_id() << " saw: "; for (auto e : v) std::cout << e << ' '; std::cout << '\n'; } int main() { using namespace std::chrono_literals; constexpr int N_READERS = 5; constexpr int LAST = -999; std::shared_mutex smtx; int product = 0; auto writer = [&smtx, &product](int start, int end) { for (int i = start; i < end; ++i) { auto data = i; { std::unique_lock<std::shared_mutex> lock(smtx); product = data; } std::this_thread::sleep_for(3ms); } smtx.lock(); // lock manually product = LAST; smtx.unlock(); }; auto reader = [&smtx, &product]() { int data = 0; std::vector<int> seen; do { { smtx.lock_shared(); // better to use: std::shared_lock lock(smtx); data = product; smtx.unlock_shared(); } seen.push_back(data); std::this_thread::sleep_for(2ms); } while (data != LAST); print(seen); }; std::vector<std::thread> threads; threads.emplace_back(writer, 1, 13); threads.emplace_back(writer, 42, 52); for (int i = 0; i < N_READERS; ++i) threads.emplace_back(reader); for (auto&& t : threads) t.join(); }
Mögliche Ausgabe
127755840 saw: 43 3 3 4 46 5 6 7 7 8 9 51 10 11 11 12 -999 144541248 saw: 2 44 3 4 46 5 6 7 7 8 9 51 10 11 11 12 -999 110970432 saw: 42 2 3 45 4 5 47 6 7 8 8 9 10 11 11 12 -999 119363136 saw: 42 2 3 4 46 5 6 7 7 8 9 9 10 11 11 12 12 -999 136148544 saw: 2 44 3 4 46 5 6 48 7 8 9 51 10 11 11 12 12 -999
[bearbeiten] Siehe auch
| sperrt den Mutex, blockiert, wenn der Mutex nicht verfügbar ist (public member function) | |
| versucht, den Mutex für gemeinsamen Besitz zu sperren, kehrt zurück, wenn der Mutex nicht verfügbar ist (public member function) | |
| entsperrt den Mutex (gemeinsamer Besitz) (public member function) |