std::shared_mutex
The std::shared_mutex
is a synchronization primitive introduced in C++17 that allows multiple threads to share read-only access while providing exclusive write access to a single thread. It is a more refined version of traditional mutexes when dealing with situations where reads are much more common than writes.
std::shared_mutex
is particularly useful in scenarios where a shared resource is mostly read and only occasionally written to, such as caching, configuration data, or reference data that is read frequently but rarely modified.
Here is a basic example where multiple threads read from a shared resource, and occasionally, one thread writes to it.
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>
#include <chrono>
std::shared_mutex sharedMutex;
int sharedResource = 0;
void reader(int id) {
for (int i = 0; i < 5; ++i) {
std::shared_lock<std::shared_mutex> lock(sharedMutex); // Acquire shared (read) lock
std::cout << "Reader " << id << " read value: " << sharedResource << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Simulate work
}
}
void writer(int id) {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::shared_mutex> lock(sharedMutex); // Acquire unique (write) lock
++sharedResource;
std::cout << "Writer " << id << " updated value to: " << sharedResource << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(150)); // Simulate work
}
}
int main() {
std::vector<std::thread> threads;
// Start several reader threads
for (int i = 0; i < 3; ++i) {
threads.push_back(std::thread(reader, i + 1));
}
// Start a writer thread
threads.push_back(std::thread(writer, 1));
// Join all threads
for (auto& thread : threads) {
thread.join();
}
return 0;
}
std::shared_lock
: In the reader function, we use std::shared_lock<std::shared_mutex>
to acquire a shared (read) lock. Multiple readers can hold this lock simultaneously, allowing them to read from sharedResource
without blocking each other.std::unique_lock
: In the writer function, we use std::unique_lock<std::shared_mutex>
to acquire an exclusive (write) lock. Only one writer can hold this lock at a time, ensuring that sharedResource
is updated without interference from other threads.std::this_thread::sleep_for
is used to simulate some work being done while the lock is held.The output will vary depending on the timing of thread execution, but it will show the reader threads reading the value of sharedResource and the writer thread updating it. Here’s a sample output:
Reader 1 read value: 0
Reader 2 read value: 0
Reader 3 read value: 0
Writer 1 updated value to: 1
Reader 1 read value: 1
Reader 2 read value: 1
Reader 3 read value: 1
Writer 1 updated value to: 2
Reader 1 read value: 2
Reader 2 read value: 2
Reader 3 read value: 2
Writer 1 updated value to: 3
std::shared_mutex
std::shared_mutex
std::shared_mutex
can significantly improve performance by reducing lock contention.std::shared_mutex
is a valuable addition to the C++ concurrency toolkit, allowing developers to optimize read-heavy workloads by enabling multiple threads to read shared data simultaneously while still ensuring safe, exclusive access when writing. It’s particularly useful in applications where data is mostly read but occasionally written, helping to improve performance and reduce unnecessary locking overhead.