Je vois que pour utiliser des objets qui ne sont pas sûrs pour les threads, nous enveloppons le code avec un verrou comme ceci:
private static readonly Object obj = new Object();
lock (obj)
{
// thread unsafe code
}
Que se passe-t-il donc lorsque plusieurs threads accèdent au même code (supposons qu'il s'exécute dans une application Web ASP.NET). Sont-ils en file d'attente? Si oui, combien de temps attendront-ils?
Quel est l'impact sur les performances en raison de l'utilisation de verrous?
Réponses:
L'
lock
instruction est traduite par C # 3.0 comme suit:En C # 4.0, cela a changé et il est maintenant généré comme suit:
Vous pouvez trouver plus d'informations sur ce qui se
Monitor.Enter
passe ici . Pour citer MSDN:La
Monitor.Enter
méthode attendra infiniment; il n'expirera pas .la source
obj
sans que l'ensemble du système ne se bloque.lock
déclaration et du moniteur: afin que vous puissiez effectuer une opération dans un thread sans avoir à vous soucier d'un autre thread qui le déblaie.C'est plus simple que vous ne le pensez.
Selon Microsoft : le
lock
mot clé garantit qu'un thread n'entre pas dans une section critique de code tandis qu'un autre thread se trouve dans la section critique. Si un autre thread essaie d'entrer un code verrouillé, il attendra, bloquera, jusqu'à ce que l'objet soit libéré.Le
lock
mot-clé appelleEnter
au début du bloc etExit
à la fin du bloc.lock
Le mot clé gère en fait laMonitor
classe à l'arrière-plan.Par exemple:
Dans le code ci-dessus, le thread entre d'abord dans une section critique, puis il se verrouille
obj
. Lorsqu'un autre thread essaie d'entrer, il essaiera également de se verrouillerobj
, qui est déjà verrouillé par le premier thread. Le deuxième thread devra attendre la libération du premier threadobj
. Lorsque le premier fil sort, un autre fil se verrouilleobj
et entre dans la section critique.la source
Non, ils ne sont pas en file d'attente, ils dorment
Une déclaration de verrouillage du formulaire
où x est une expression d'un type de référence, équivaut précisément à
Vous avez juste besoin de savoir qu'ils attendent les uns des autres, et qu'un seul thread entrera pour verrouiller le bloc, les autres attendront ...
Le moniteur est entièrement écrit en .net donc c'est assez rapide, regardez aussi la classe Moniteur avec réflecteur pour plus de détails
la source
lock
instruction a légèrement changé en C # 4: blogs.msdn.com/b/ericlippert/archive/2009/03/06/…Les verrous empêcheront les autres threads d'exécuter le code contenu dans le bloc de verrouillage. Les threads devront attendre que le thread à l'intérieur du bloc de verrouillage soit terminé et que le verrouillage soit libéré. Cela a un impact négatif sur les performances dans un environnement multithread. Si vous devez le faire, vous devez vous assurer que le code dans le bloc de verrouillage peut être traité très rapidement. Vous devriez essayer d'éviter des activités coûteuses comme l'accès à une base de données, etc.
la source
L'impact sur les performances dépend de la façon dont vous verrouillez. Vous pouvez trouver une bonne liste d'optimisations ici: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
Fondamentalement, vous devriez essayer de verrouiller le moins possible, car cela met votre code d'attente en veille. Si vous avez des calculs lourds ou du code de longue durée (par exemple, le téléchargement de fichiers) dans un verrou, cela entraîne une énorme perte de performances.
la source
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]. Le plus grand danger est que si les exigences évoluent au-delà de ce que ces techniques peuvent gérer, il peut être difficile d'adapter le code pour gérer cela.La partie de l'instruction lock ne peut être exécutée que par un seul thread, donc tous les autres threads l'attendront indéfiniment, le thread qui détient le verrou se termine. Cela peut entraîner un soi-disant blocage.
la source
L'
lock
instruction est traduite en appels aux méthodesEnter
et .Exit
Monitor
L'
lock
instruction attendra indéfiniment que l'objet de verrouillage soit libéré.la source
le verrou est en fait la classe Monitor cachée .
la source