Le code suivant entraînera-t-il un blocage à l'aide de C # sur .NET?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Réponses:
Non, pas tant que vous vous verrouillez sur le même objet. Le code récursif a effectivement déjà le verrou et peut donc continuer sans entrave.
lock(object) {...}
est un raccourci pour utiliser la classe Monitor . Comme Marc le souligne ,Monitor
autorise la rentrée , donc des tentatives répétées de verrouillage sur un objet sur lequel le thread actuel a déjà un verrou fonctionneront très bien.Si vous commencez à verrouiller différents objets, c'est à ce moment-là que vous devez faire attention. Portez une attention particulière à:
Si vous enfreignez l'une de ces règles, vous êtes pratiquement assuré d'avoir des problèmes de blocage à un moment donné .
Voici une bonne page Web décrivant la synchronisation des threads dans .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Verrouillez également le moins d'objets possible à la fois. Pensez à appliquer des verrous à gros grains lorsque cela est possible. L'idée étant que si vous pouvez écrire votre code de manière à ce qu'il y ait un graphe d'objets et que vous puissiez acquérir des verrous à la racine de ce graphe d'objets, alors faites-le. Cela signifie que vous avez un verrou sur cet objet racine et que vous n'avez donc pas à vous soucier autant de la séquence dans laquelle vous acquérez / libérez les verrous.
(Une remarque supplémentaire, votre exemple n'est pas techniquement récursif. Pour qu'il soit récursif, il
Bar()
devrait s'appeler lui-même, généralement dans le cadre d'une itération.)la source
Eh bien,
Monitor
permet la rentrée, donc vous ne pouvez pas vous bloquer ... donc non: cela ne devrait pas fairela source
Si un thread détient déjà un verrou, il ne se bloquera pas. Le framework .Net garantit cela. Vous devez seulement vous assurer que deux threads n'essaient pas d'acquérir les mêmes deux verrous dans le désordre par les chemins de code.
Le même thread peut acquérir le même verrou plusieurs fois, mais vous devez vous assurer de libérer le verrou le même nombre de fois que vous l'avez acquis. Bien sûr, tant que vous utilisez le mot-clé "lock" pour ce faire, cela se produit automatiquement.
la source
Non, ce code n'aura pas de verrous morts. Si vous voulez vraiment créer un blocage le plus simple, il faut au moins 2 ressources. Considérez le scénario du chien et des os. 1. Un chien a un contrôle total sur 1 os, donc tout autre chien doit attendre. 2. 2 chiens avec 2 os sont au minimum requis pour créer une impasse lorsqu'ils verrouillent leurs os respectivement et recherchent également d'autres os.
.. et ainsi de suite n chiens et m os et provoquent des blocages plus sophistiqués.
la source