62 votes

Pourquoi les verrous imbriqués ne provoquent-ils pas de blocage ?

Pourquoi ce code ne provoque-t-il pas d'impasse ?

   private static readonly object a = new object();

...

   lock(a)
   {
      lock(a)
      {
         ....
      }
   }

58voto

Anon. Points 26829

Si un thread détient déjà un verrou, il peut le reprendre sans problème.


Quant à pourquoi (et pourquoi c'est une bonne idée), considérons la situation suivante, où nous avons un ordre de verrouillage défini ailleurs dans le programme de a -> b :

void f()
{
    lock(a)
    { /* do stuff inside a */ }
}

void doStuff()
{
    lock(b)
    {
        //do stuff inside b, that involves leaving b in an inconsistent state
        f();
        //do more stuff inside b so that its consistent again
    }
}

Oups, nous venons d'enfreindre notre ordre de verrouillage et nous nous retrouvons dans une impasse potentielle.

Nous realmente doit être capable de faire ce qui suit :

function doStuff()
{
    lock(a)
    lock(b)
    {
        //do stuff inside b, that involves leaving b in an inconsistent state
        f();
        //do more stuff inside b so that its consistent again
    }
}

Ainsi, l'ordre des verrous est maintenu, sans qu'il y ait de blocage automatique lorsque nous appelons f() .

25voto

Davy8 Points 12458

En lock utilise un verrou réentrant, ce qui signifie que le thread en cours possède déjà le verrou et qu'il n'essaie donc pas de le réacquérir.

Une impasse se produit si

Le thread 1 acquiert le verrou A
Le fil 2 acquiert le verrou B
Le thread 1 tente d'acquérir le verrou B (attend que le thread 2 ait terminé) Le fil d'exécution 2 tente d'acquérir le verrou A (attend que le fil d'exécution 1 ait terminé).

Les deux threads sont maintenant en attente l'un de l'autre et sont donc dans l'impasse.

12voto

Dan J Points 10269

De article 8.12 de la spécification du langage C# :

Alors qu'une clause d'exclusion mutuelle le code s'exécutant dans le même d'exécution peut également obtenir et libérer le verrou. Toutefois, le code s'exécutant dans d'autres est empêché d'obtenir le verrou jusqu'à ce que le verrou soit libéré.

Il devrait être évident que le système interne lock est dans le même fil que l'extérieur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X