boost::shared_mutex or std::shared_mutex (C ++ 17) can be used for one recorder, for multiple readers. As a training exercise, I put together a simple implementation that uses spinlock and has other limitations (for example, an honesty policy), but it is obviously not intended for use in real applications.
The idea is that the mutex keeps the reference count equal to zero if no thread holds the lock. If> 0, the value represents the number of readers who have access. If -1, one author has access.
Is this the correct implementation (in particular, with the minimum memory order used), in which there are no data races?
#include <atomic> class my_shared_mutex { std::atomic<int> refcount{0}; public: void lock() // write lock { int val; do { val = 0; // Can only take a write lock when refcount == 0 } while (!refcount.compare_exchange_weak(val, -1, std::memory_order_acquire)); // can memory_order_relaxed be used if only a single thread takes write locks ? } void unlock() // write unlock { refcount.store(0, std::memory_order_release); } void lock_shared() // read lock { int val; do { do { val = refcount.load(std::memory_order_relaxed); } while (val == -1); // spinning until the write lock is released } while (!refcount.compare_exchange_weak(val, val+1, std::memory_order_acquire)); } void unlock_shared() // read unlock { // This must be a release operation (see answer) refcount.fetch_sub(1, std::memory_order_relaxed); } };
c ++ multithreading mutex c ++ 11 stdatomic
Lwimsey
source share