Traitement des mutex dans les types mobiles en C
Comme vous l'avez mentionné, std::mutex n'est ni mobile ni copiable, ce qui présente un défi lorsque travailler avec des classes qui détiennent des mutex. Pour rendre un type mobile tout en préservant la sécurité des threads, envisagez l'approche suivante :
Créez un constructeur de déplacement qui verrouille le mutex de l'objet déplacé depuis (a) à l'aide d'un WriteLock :
A(A&& a) { WriteLock rhs_lk(a.mut_); field1_ = std::move(a.field1_); field2_ = std::move(a.field2_); }
L'opérateur d'affectation de déplacement est plus délicat, car d'autres threads peuvent accéder à l'un ou l'autre le gauche ou le droit de l'affectation :
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; }
Si vous devez prendre en charge la sémantique de copie, créez un constructeur de copie qui verrouille le mutex de l'objet copié à partir de (a) à l'aide d'un ReadLock :
A(const A& a) { ReadLock rhs_lk(a.mut_); field1_ = a.field1_; field2_ = a.field2_; }
Si vous avez également besoin d'une affectation de copie opérateur, suivez un modèle similaire :
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; }
La protection des membres et des fonctions gratuites qui accèdent à l'état de la classe est cruciale pour la sécurité des threads. Par exemple, voici une fonction d'échange :
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_); } }
Enfin, rappelez-vous que std::shared_timed_mutex en C 14 permet des optimisations possibles dans les situations où plusieurs threads tentent de copier-construire à partir du même objet.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!