C の Movable Type でのミューテックスの処理
あなたが述べたように、std::mutex は移動可能でもコピー可能でもありません。ミューテックスを保持するクラスを操作します。スレッドの安全性を維持しながら型を移動可能にするには、次のアプローチを検討してください。
WriteLock を使用して、(a) から移動されるオブジェクトのミューテックスをロックする移動コンストラクターを作成します。
A(A&& a) { WriteLock rhs_lk(a.mut_); field1_ = std::move(a.field1_); field2_ = std::move(a.field2_); }
移動代入演算子は、他の演算子と同様に複雑です。スレッドは代入の lhs または rhs にアクセスしている可能性があります:
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; }
コピー セマンティクスをサポートする必要がある場合は、オブジェクトのミューテックスをロックするコピー コンストラクターを作成します。 ReadLock を使用して (a) からコピーされました:
A(const A& a) { ReadLock rhs_lk(a.mut_); field1_ = a.field1_; field2_ = a.field2_; }
コピー代入演算子も必要な場合は、同様のパターンに従います。
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; }
クラスの状態にアクセスするメンバーと自由関数の保護スレッドの安全性にとって重要です。たとえば、スワップ関数は次のとおりです。
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_); } }
最後に、C 14 の std::shared_timed_mutex により、複数のスレッドが同じオブジェクトからコピー構築を試みる状況で最適化が可能になることを思い出してください。
以上がC で内部ミューテックスを持つ Movable Type を作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。