C++ Read-Write Lock Pattern: Real-World Engineering Guide
C++ Read-Write Lock Pattern: Real-World Engineering Guide
Problem Solved
Optimize concurrent access to shared data that is read frequently but rarely written.
How It Works
- Multiple readers allowed at the same time
- Writers must be exclusive (no readers, no other writers)
- Uses shared locks for reads, exclusive locks for writes
STL Usage
#include <shared_mutex>
#include <map>
#include <string>
#include <vector>
#include <thread>
using namespace std;
class ThreadSafeMap {
private:
map<string, int> data_;
shared_mutex rw_mutex_;
public:
// Read operation - shared lock
int get(const string& key) {
shared_lock<shared_mutex> lock(rw_mutex_);
auto it = data_.find(key);
return (it != data_.end()) ? it->second : -1;
}
// Write operation - exclusive lock
void set(const string& key, int value) {
unique_lock<shared_mutex> lock(rw_mutex_);
data_[key] = value;
}
// Read operation
bool contains(const string& key) {
shared_lock<shared_mutex> lock(rw_mutex_);
return data_.find(key) != data_.end();
}
};
Example
#include <iostream>
#include <chrono>
using namespace std;
void readWriteLockExample() {
ThreadSafeMap cache;
// Multiple readers
vector<thread> readers;
for (int i = 0; i < 10; ++i) {
readers.emplace_back([&cache, i]() {
for (int j = 0; j < 100; ++j) {
cache.get("key" + to_string(j % 10));
}
});
}
// Single writer
thread writer([&cache]() {
for (int i = 0; i < 10; ++i) {
cache.set("key" + to_string(i), i);
this_thread::sleep_for(chrono::milliseconds(10));
}
});
for (auto& t : readers) t.join();
writer.join();
}
Use Cases
- Caches: Frequently read, occasionally updated
- Configuration stores: Read-heavy, rare updates
- File metadata: Many readers, few writers
- Lookup tables: Read operations dominate
Key Takeaways
- Significant performance improvement for read-heavy workloads
- Allows concurrent reads
- Exclusive writes ensure consistency
- C++17
std::shared_mutexsupport
Things to Be Careful About
- Writer starvation: Readers can starve writers
- Upgrade deadlock: Can’t upgrade read lock to write lock
- Fairness: May need fair locks for balanced access
- Overhead: More complex than simple mutex
Summary
Read-Write locks optimize concurrent access for read-heavy workloads, providing significant performance improvements.