Home >Backend Development >C++ >How to Make a Movable Type with Internal Mutexes in C ?

How to Make a Movable Type with Internal Mutexes in C ?

Linda Hamilton
Linda HamiltonOriginal
2024-12-05 11:01:11752browse

How to Make a Movable Type with Internal Mutexes in C  ?

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:

Move Constructor

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_);
}

Move Assignment

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;
}

Copy Constructor

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_;
}

Copy Assignment

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;
}

Additional Notes

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn