Pourquoi passer mutex comme paramètre à une fonction appelée par un fil?
À certains endroits, j'ai vu des gens de la création d'un pool de threads et la création de threads et de l'exécution d'une fonction avec les threads. Tout en appelant cette fonction boost::mutex est passé par référence. Pourquoi il est fait? Je crois que vous pouvez avoir un mutex déclaré dans la fonction appelée elle-même ou peut-être a déclaré un membre de la classe ou mondial. Quelqu'un peut expliquer?
par exemple
myclass::processData()
{
boost::threadpool::pool pool(2);
boost::mutex mutex;
for (int i =0; data<maxData; ++data)
pool.schedule(boost::bind(&myClass::getData, boost_cref(*this), boost::ref(mutex)));
}
Puis,
myClass::getData(boost::mutex& mutex)
{
boost::scoped_lock(mutex) //Why can't we have class member variable mutex or
//local mutex here
//Do somethign Here
}
Vous devez ajouter un exemple particulier où il est utilisé. C'est probablement à cause de la sémantique qui sont mis en œuvre dans l'exemple, et ne peut pas être répondu sans contexte à tous (sauf si vous voulez générique parce que ou sens réponses)
OriginalL'auteur polapts | 2011-09-26
Vous devez vous connecter pour publier un commentaire.
Mutex sont non-copiable objets, et tandis qu'ils peuvent être les membres d'une classe, il serait grandement compliquer un parent de la classe de copie capacité. Ainsi, une méthode préférée, si un certain nombre d'instances de la classe doivent partager les mêmes données, serait de créer le mutex en tant que données statiques-membre. Sinon, si le mutex n'avaient qu'à être enfermé dans une instance de la classe elle-même, vous pouvez créer un pointeur vers un mutex comme un non-statique des données-membre, et chaque copie de la classe aurait-il propres alloués dynamiquement mutex (et restent copiable si c'est une exigence).
Dans l'exemple de code ci-dessus, ce qui est en gros est il est un mutex global transmis dans le pool de threads par référence. Qui permet à tous les threads partage les mêmes emplacements de mémoire pour créer un verrou exclusif sur la mémoire en utilisant la même mutex, mais sans la contrainte d'avoir à gérer le non-copiable aspect du mutex. Le mutex dans cet exemple de code pourrait également être statique des données membres de la classe
myClass
plutôt qu'un mutex global qui est passé par référence, en partant de l'hypothèse que chaque thread besoin de verrouiller la mémoire qui est accessible dans le monde entier à partir de chaque thread.Le problème avec un mutex est que ce n'est que localement version accessible du mutex ... donc quand un thread verrouille le mutex dans le but de partager quelques mondialement accessibles des données, les données ne sont pas protégés, car tous les autres thread aura ses propres locaux mutex qui peut être verrouillé et déverrouillé. Il défait le point de l'ensemble de l'exclusion mutuelle.
Désolé, je ne voulais pas dire que vous pas de le faire ... je voulais juste dire que si vous en faites une non-statique de données des membres, de la création d'un correctement copiable classe est beaucoup plus difficile (à la fin c'est pas vraiment va être copiable, vous devez stocker un pointeur vers un mutex, puis de libérer et de réaffecter le mutex dans la copie, ce qui n'est pas un "vrai" copie de chaque membre de la classe). Je vais revoir ma réponse pour rendre cela plus clair.
... tout dépend de ce que la définition de votre objet (sémantiquement) Dans la plupart des cas, le mutex ne fait pas partie de l'état de l'objet, mais est un utilitaire permettant de s'assurer que l'état réel de la classe ne peut pas être vu dans une position intermédiaire incorrect (invariants cassé) état lorsque utilisé dans un environnement multithread.
Oui, je suis d'accord, mais dans l'exemple de code donné, alors qu'il n'était pas exprimé explicitement, il semble qu'en raison d'un pointeur statique
myClass
méthode a été passé àbind
sans un pointeur vers une instance demyClass
, il y a certaines données partagées entre les threads qui aurait besoin d'un mutex accessible à partir de plus d'une seule instance demyClass
.OriginalL'auteur Jason
la création d'une nouvelle mutex à l'entrée protège rien.
si vous considérez la déclaration d'une statique (ou global) mutex pour protéger les non-membres statiques, alors vous pouvez aussi bien écrire le programme comme un seul programme multi-threadé (ok, il y a quelques cas particuliers). une statique de la serrure serait de bloquer tous les threads, mais (en supposant concours); il est équivalent à "un maximum d'un seul thread peut fonctionner dans cette méthode, le corps en une seule fois". la déclaration d'une statique mutex pour protéger les données statiques sont beaux. comme David Rodriguez - dribeas formulée de manière succincte dans une autre réponse, les commentaires de: "Le mutex doit être au niveau des données qui sont protégés".
vous peut déclarer une variable de membre par exemple, qui devrait prendre la forme généralisée:
cette approche est très bien, et dans certains cas idéal. il a de sens que dans la plupart des cas, lorsque vous êtes à la construction d'un système où les instances de l'intention à l'abrégé de verrouillage mécanique et les erreurs de leurs clients. un inconvénient est qu'il peut exiger plus d'acquisitions, et il nécessite généralement plus complexes mécanismes de verrouillage (par exemple réentrant). en plus des acquisitions: le client peut savoir qu'une instance est utilisé dans un seul fil de discussion: pourquoi serrure à tous dans ce cas? ainsi, un tas de petits threads méthodes d'introduire une surcharge importante. avec dispositif de verrouillage, vous voulez obtenir dans et hors des zones protégées les plus brefs délais (sans introduire de nombreuses acquisitions), de sorte que les sections critiques sont souvent des opérations plus importantes que la moyenne.
si l'interface publique nécessite ce verrou comme un argument (comme dans votre exemple), c'est un signal que votre conception peut être simplifié par la privatisation de verrouillage (la prise de fonction de l'objet dans un thread de manière sûre, plutôt que de passer le verrouillage de l'extérieur, tenue de ressources).
à l'aide d'un (ou lié ou associé) de verrouillage, vous pouvez éventuellement réduire les acquisitions (ou bloqué). cette approche permet également d'ajouter de verrouillage à une instance après le fait. il permet également au client de configurer la façon dont la serrure fonctionne. le client peut utiliser moins de verrous par le partage (parmi un ensemble d'instances). même un simple exemple de composition peut illustrer cela (supportant à la fois les modèles):
compte tenu de la complexité de certains multithread systèmes, en poussant la responsabilité de la bonne fermeture sur le client peut être une très mauvaise idée.
les deux modèles (lié et en tant que membre de la variable) peut être utilisé efficacement. ce qui est mieux dans un scénario donné, varie en fonction du problème.
comme un général approche: oui, c'est l'une des multiples utilisable approches pour garantir que vos implémentations sont thread-safe (l'autre étant l'approche de l'OP). la granularité est également important si vous voulez minimiser les acquisitions et verrouillage fois. un niveau de classe de verrouillage peut être trop faible dans certains cas, cela permettra de mener à bien des acquisitions. une plus grande (global ou document de base) de verrouillage ne sera pas idéale dans de nombreux cas, parce que le temps enfermé par acquisition augmente et il y a nettement plus de chances que les autres d'attendre pendant ce temps.
OriginalL'auteur justin
L'aide des mutex est faux: pool de threads peut en appeler plusieurs fonction des cas, et ils devraient travailler avec le même mutex. Membre de la classe est OK. En passant mutex à la fonction rend plus générique et plus lisible. L'appelant peut décider qui mutex: membre de la classe ou quoi que ce soit d'autre.
OriginalL'auteur Alex F