Thread-Safe Movability with Non-Movable Mutexes in C
When dealing with movable types, such as std::mutex, in C thread-safe programming can be challenging. By default, std::mutex is neither movable nor copyable, hindering the creation of thread-safe movable objects.
To make a class containing a mutex movable and maintain thread safety, consider the following approach:
1. Enable Mutability:
Make the mutex member mutable (e.g., mutable std::mutex mut_;) to allow modification during move operations.
2. Move Constructor:
Lock the mutex of the object being moved from before assigning its members. This prevents data corruption from concurrent access.
A(A&& a) { WriteLock rhs_lk(a.mut_); field1_ = std::move(a.field1_); field2_ = std::move(a.field2_); }
3. Move Assignment Operator:
Protect the move assignment using synchronization primitives. Since access from multiple threads is possible, lock both the left-hand side (lhs) and right-hand side (rhs) mutexes before performing assignments.
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; }
4. Copy Members (Optional):
If copy members are also required, use ReadLock (instead of WriteLock) to allow concurrent reading from the object being copied from.
A(const A& a) { ReadLock rhs_lk(a.mut_); field1_ = a.field1_; field2_ = a.field2_; }
5. Additional Considerations:
By following these guidelines, you can ensure that your movable classes remain thread-safe even when using non-movable mutexes.
The above is the detailed content of How Can I Make My C Classes with Non-Movable Mutexes Both Movable and Thread-Safe?. For more information, please follow other related articles on the PHP Chinese website!