Dealing with Mutexes in Movable Types in C
As you mentioned, std::mutex is neither movable nor copyable, presenting a challenge when working with classes that hold mutexes. To make a type movable while maintaining thread safety, consider the following approach:
Create a move constructor that locks the mutex of the object being moved from (a) using a WriteLock:
A(A&& a) { WriteLock rhs_lk(a.mut_); field1_ = std::move(a.field1_); field2_ = std::move(a.field2_); }
The move assignment operator is trickier, as other threads may be accessing either the lhs or rhs of the assignment:
A& operator=(A&& a) { if (this != &a) { WriteLock lhs_lk(mut_, std::defer_lock); WriteLock rhs_lk(a.mut_, std::defer_lock); std::lock(lhs_lk, rhs_lk); field1_ = std::move(a.field1_); field2_ = std::move(a.field2_); } return *this; }
If you need to support copy semantics, create a copy constructor that locks the mutex of the object being copied from (a) using a ReadLock:
A(const A& a) { ReadLock rhs_lk(a.mut_); field1_ = a.field1_; field2_ = a.field2_; }
If you also need a copy assignment operator, follow a similar pattern:
A& operator=(const A& a) { if (this != &a) { WriteLock lhs_lk(mut_, std::defer_lock); ReadLock rhs_lk(a.mut_, std::defer_lock); std::lock(lhs_lk, rhs_lk); field1_ = a.field1_; field2_ = a.field2_; } return *this; }
Protecting members and free functions that access the state of the class is crucial for thread safety. For example, here's a swap function:
friend void swap(A& x, A& y) { if (&x != &y) { WriteLock lhs_lk(x.mut_, std::defer_lock); WriteLock rhs_lk(y.mut_, std::defer_lock); std::lock(lhs_lk, rhs_lk); using std::swap; swap(x.field1_, y.field1_); swap(x.field2_, y.field2_); } }
Finally, recall that std::shared_timed_mutex in C 14 allows for possible optimizations in situations where multiple threads attempt to copy-construct from the same object.
The above is the detailed content of How to Make a Movable Type with Internal Mutexes in C ?. For more information, please follow other related articles on the PHP Chinese website!