I came across an std::shared_mutex
in C++17
. what exactly is std::shared_mutex
and how it is different from std::mutex
?
A mutex
is either locked or not.
A shared_mutex
is either locked exclusively, or locked shared, or not.
Any number of clients can shared lock a shared mutex.
If anyone has it exclusive locked, nobody else can hold any locks.
On windows, this is the SWRLOCK
type -- and in fact, this lock is typically used to implement read-write locks; many readers allowed, but writing must be exclusive.
Here is some sample code to create two template wrappers for shared and non-shared mutexes. In one case, we have read and write operations that aquire different locks. In the other, we just have access:
template
struct mutex_guarded {
template
auto access( F&& f ) {
auto l = lock();
return std::forward(f)(t);
}
template
auto access( F&& f ) const {
auto l = lock();
return std::forward(f)(t);
}
mutex_guarded(mutex_guarded const&)=delete;
mutex_guarded& operator=(mutex_guarded const&)=delete;
template
mutex_guarded( Ts&&...ts ):t(std::forward(ts)...){}
mutex_guarded()=default;
protected:
mutable M m;
T t;
auto lock() { return std::unique_lock(m); }
};
template
struct shared_mutex_guarded:private mutex_guarded {
using base = mutex_guarded;
template
auto read( F&& f ) const { return access(std::forward(f)); }
template
auto write( F&& f ) { return access(std::forward(f)); }
using base::base;
protected:
using base::access;
template
auto access( F&& f ) const {
auto l = lock();
return std::forward(f)(this->t);
}
using base::lock;
auto lock() const { return std::shared_lock(this->m); }
};