Le verrouillage d'une seule variable boolean lorsque le multithreading?
Récemment, j'ai vu ce code dans un Site web, et ma question est la suivante:
private bool mbTestFinished = false;
private bool IsFinished()
{
lock( mLock )
{
return mbTestFinished;
}
}
internal void SetFinished()
{
lock( mLock )
{
mbTestFinished = true;
}
}
Dans un environnement multithread, est vraiment nécessaire pour verrouiller l'accès à la mbTestFinished
?
- Il est le plus démontrable mécanisme pour s'assurer qu'il n'est pas un CPU-en cache de lecture (qui ne fonctionne pas bien entre les threads) -
volatile
serait trop de travail, mais pour des raisons qui sont trop complexes (ce n'est pas l'intention devolatile
, mais plutôt un effet secondaire) - J'ai toujours pensé que c'était l'intention de
volatile
; toute chance que vous pourriez déposer un bon lien qui explique ce qu'est? - Cette répondre on a une idée.
- Merci! Avoir lu, il semble que c'est l'usage prévu, ou
lock
aussi qu'accidentellement atteint l'effet désiré, n'est-ce pas? - Bien en quelque sorte. Sauf que
lock
en fait de garantir une fraîcheur lire parce que la barrière de la mémoire s'affiche avant le lire.volatile
met la barrière de la mémoire après la lecture. Je discuter de cette tangentiellement lors de l'explication de commentThread.VolatileRead
est mis en œuvre au bas de ma réponse ici.
Vous devez vous connecter pour publier un commentaire.
Oui, elle est nécessaire. .Net de l'environnement utilise certaines optimisations, et parfois, si un emplacement de mémoire est souvent accessibles, les données sont déplacées dans les registres du CPU. Donc, dans ce cas, si mbTestFinished est dans un PROCESSEUR inscrire, puis un fil de la lecture il peut obtenir une valeur erronée. Ainsi, à l'aide de la volatilité de la clé assure, tous les accès à cette variable est fait à l'emplacement de la mémoire, pas à les registres.
A l'inverse, je n'ai aucune idée de la fréquence de cette occurence. Cela peut se produire à une fréquence très faible.
À mon avis, non, le verrouillage est superflu ici, pour deux raisons:
long
par exemple, d'où le verrouillage n'est pas nécessaire.volatile
est assez. Il est vrai que lalock
introduit implicitement une clôture, mais depuis lelock
n'est pas nécessaire pour l'atomicité, lavolatile
est assez.mLock
est prise, la conversion de lavolatile
pourrait casser des choses.Si mLock est SEULEMENT pour la variable mbTestFinished, alors c'est un peu exagéré. Au lieu de cela, vous pouvez utiliser volatils ou Contrefil, parce que les deux sont en Mode Utilisateur constructions pour la synchronisation des threads. de verrouillage (ou Moniteur) est un Construction Hybride, dans le sens qu'il est bien optimisé pour éviter de passer du/de la en Mode Noyau chaque fois que possible. Le livre "CLR via C#" a une discussion approfondie de ces concepts.