Je veux exécuter une méthode en lecture seule sur un objet marqué comme const code>, mais afin de faire ce fil en toute sécurité, j'ai besoin de verrouiller un rédacteur-écrivain de lecteurs:
inline void read_lock() const {
pthread_rwlock_rdlock(const_cast<pthread_rwlock_t*>(&rwlock_));
}
5 Réponses :
faire le verrouillage mutable code>. p>
rendre le verrouillage mutable ceci est un scénario courant dans lequel mutable est utilisé. Une requête en lecture seule d'un objet est (comme son nom l'indique) une opération qui ne doit pas nécessiter d'accéder à des non-Const. Un mutable est considéré comme une bonne pratique lorsque vous souhaitez pouvoir modifier des parties d'un objet qui ne sont pas visibles ou ont des effets secondaires observables à l'objet. Votre verrouillage est utilisé pour assurer un accès séquentiel aux données de l'objet et la modification de celle-ci n'effectue pas les données contenues dans l'objet, ni d'effets secondaires observables à des appels ultérieurs afin qu'il honore toujours la const-ness de l'objet. p> p>
Une autre façon de l'expliquer: la méthode C ++ const est la conscience logique, pas la conscience physique. Il est normal de changer l'état physique (prendre une serrure, modifier un cache) aussi longtemps que logiquement, l'état d'objet est inchangé.
Par logiquement, nous entendons "d'un observateur à l'extérieur" >>, c'est-à-dire s'il n'y a aucun effet sur le résultat des méthodes publiques / protégées de l'objet (oui, protégé également, car une classe dérivée ne devrait pas savoir sur la mise en œuvre de sa base ).
Merci pour toutes les réponses détaillées et commentaires. J'ai appris plus sur C ++ dans quelques semaines sur Stackoverflow puis en lisant des tonnes de C ++ Gotchas et d'autres livres en mois.
Pour résoudre le problème réel, déclarez la serrure aussi mutable. P>
Ce qui suit est maintenant mon avis professionnel: p>
Le compilateur a raison de se plaindre et vous avez raison de trouver cette légère offensive. Si l'exécution d'une opération en lecture seule nécessite une serrure et que les verrous doivent être écrits pour verrouiller, vous devriez probablement rendre la requête en lecture seule nécessite un accès non constitué. P>
EDIT: D'accord, je vais mordre. J'ai vu ce type de motif causer de grandes coups de perfection dans des endroits où vous ne vous attendriez pas. Est-ce que quelqu'un ici savoir comment Juste parce que vous voulez que l'accès en lecture seule ne signifie pas que vous devriez cacher le fait que vous devez verrouiller pour l'obtenir. P> tolower code> ou
Toupper code> peut devenir un important goulot d'étranglement si on l'appelle assez souvent, même avec les paramètres régionaux ASCII par défaut? Dans une implémentation particulière de la bibliothèque d'exécution C construite pour multithreading, il y avait une serrure prise pour interroger la locale actuelle pour ce fil. Appelant
tolower code> de l'ordre de 10000 fois ou plus a abouti à plus d'un coup de lecture de PERF que de lire un fichier à partir de disque. P>
Une fonction const code> ne doit pas modifier tout comportement observable d'une classe, mais il est souvent raisonnable de modifier les variables d'éléments. Dans ce cas, il semble que vous modifiez quelque chose pour verrouiller d'autres threads pendant une opération de lecture. L'opération de lecture est
const code>, je suppose et la variable modifiée est uniquement d'accès à la séquence, il devrait donc probablement être
mutable code>.
C'est vrai, mais je discute que invoquant une serrure d'accès en lecture seule est quelque chose que vous souhaitez être observable.
J'essayais de modifier la serrure afin que l'accès en lecture seule fonctionne sur les serrures de const.
Je comprends que. Ce que je dis, c'est que besoin de verrouiller pour fournir un accès en lecture seule est également une odeur de code. Au moins pour moi. Certes dans le contexte de la plupart des questions Stackoverflow qui ne répondent pas à votre question, mais je sentais que cela témoigne de mentionner.
@MSN: Non, à l'aide d'un verrouillage d'accès exclusif ne modifie pas l'état observable de l'objet. Toute opération effectuée sur l'objet avant et après que l'opération de const a lieu donnera exactement le même résultat. Le fait qu'il affecte la rapidité avec laquelle vous percevez l'état et que l'état que vous percevez est totalement indépendant. Ensuite, devoir verrouiller une opération de lecture n'est pas une odeur de code, mais plutôt une nécessité si l'opération de lecture n'est pas atomique. Sinon, un fil d'écriture pourrait changer l'objet entre les deux et vous pourriez finir de lire des valeurs non valides.
Je comprends que cela ne fait pas partie de l'état observable de l'objet. Ce n'est pas mon point. En fait, mon point n'a rien à voir avec cette question apparemment. Je comprends pourquoi vous voudriez faire cela. Basé sur mon expérience, c'est la mauvaise chose à faire. Avoir une seule classe être à la fois responsable d'une vue en lecture seule valide et de synchroniser l'accès à ses internes est une odeur de code pour moi b>. J'ai même déclaré que cela importe même dans les cas les plus triviaux. En d'autres termes, avoir un objet être responsable de sa propre sécurité du thread signifie probablement que vous faites trop de choses dans cet objet.
Oui, utilisez mutable. Il est conçu pour cet objectif très utile: où tout le contexte de la fonction est constitué (c'est-à-dire un accesseur ou une autre action logiquement en lecture seule.) Mais lorsque certains éléments d'accès en écriture sont nécessaires pour un mutex ou un compteur de référence, etc.
La fonction devrait être constante, même si elle verrouille un mutex en interne. Cela fait de sorte que le code thread-neutre sans avoir à exposer les détails que je présume que vous essayez de faire. P>
Il y a très i> peu d'endroits où En fait, je dirais que lorsque vous voyez const_cast dans une fonction Const, vous devez commencer par faire la fonction non constituée (très peu de temps après que vous devriez Débarrassez-vous du const_cast et rendez la fonction const à nouveau) p> p> const_cast <> code> doit être légitimement utilisé et ce n'est pas l'un d'entre eux. Utiliser Const Cast ON sur un objet, surtout dans une fonction Const est un cauchemar de maintenance de code. Envisagez: p>
Eh bien, si nous ne sommes pas autorisés à modifier la déclaration de la variable, Const_cast vient à la rescousse. Sinon, le rendre mutable est la solution. P>