std::shared...lock_shared(3)
π std::shared_mutex::lock_shared β C++ Standard Libary, section 3 π
okay so this page is std::shared...lock_shared(3) from the C++ Standard Libary (yes, that exact spelling up top, bestie). Itβs giving shared-lock era since C++17, and itβs lowkey iconic. Letβs go π«Ά
β¨ NAME β¨
std::shared_mutex::lock_shared β std::shared_mutex::lock_shared
πΈ Synopsis πΈ
void lock_shared(); (since C++17)
Grabs shared ownership of the mutex. If another thread is holding the mutex in exclusive ownership, a call to lock_shared will block execution until shared ownership can be acquired. Itβs literally waiting its turn, no cap. π
If lock_shared is called by a thread that already owns the mutex in any mode β exclusive or shared β the behavior is undefined. π¨ Not a cute experiment, bestie. Do not.
If more than the implementation-defined maximum number of shared owners already locked the mutex in shared mode, lock_shared blocks execution until the number of shared owners is reduced. The maximum number of owners is guaranteed to be at least 10000. So yes, it can hit a full house and then you wait. π
A prior unlock() operation on the same mutex synchronizes-with (as defined in std::memory_order) this operation. β¨ synchronization moment β¨
π Parameters π
(none) β nothing to pass in, zero, nada, periodt. π«Ά
π«Ά Return value π«Ά
(none) β no return value, no leftovers. π
π¨ Exceptions π¨
Throws std::system_error when errors occur, including errors from the underlying operating system that would prevent lock from meeting its specifications. The mutex is not locked in the case of any exception being thrown. So if it throws, no lock is left hanging β noted. π
π¦ Notes π¦
lock_shared() is usually not called directly: std::shared_lock is used to manage shared locking. Use the wrapper, itβs the main character here. π
π Example π
// Run this code π
#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();
}
π¬ Possible output π¬
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
π See also π
lockβ locks the mutex, blocks if the mutex is not available (public member function)try_lock_sharedβ tries to lock the mutex for shared ownership, returns if the mutex is not available (public member function)unlock_sharedβ unlocks the mutex (shared ownership) (public member function)
mwah π β source: http://cppreference.com; date: 2024.06.10; page: std::shared...lock_shared(3). Share-lock responsibly and stay iconic, bestie π
β¨π«Ά
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms