117 votes

Surveiller vs verrouiller

Quand est-il approprié d'utiliser soit la classe Monitor ou le mot-clé lock pour la sécurité des threads en C#?

EDIT: Il semble, d'après les réponses jusqu'à présent, que lock est une abréviation pour une série d'appels à la classe Monitor. Pour quoi exactement l'appel à lock est-il une abréviation? Ou plus explicitement,

class LockVsMonitor
{
    private readonly object LockObject = new object();
    public void DoThreadSafeSomethingWithLock(Action action)
    {
        lock (LockObject)
        {
            action.Invoke();
        }
    }
    public void DoThreadSafeSomethingWithMonitor(Action action)
    {
        // Qu'est-ce qui va ici ?
    }
}

Update

Merci à tous pour votre aide : J'ai posté une autre question en guise de suivi aux informations que vous avez tous fournies. Puisque vous semblez bien versés dans ce domaine, j'ai posté le lien : Qu'est-ce qui ne va pas avec cette solution de verrouillage et de gestion des exceptions verrouillées?

100voto

CodesInChaos Points 60274

Eric Lippert parle de cela dans son blog : Les verrous et les exceptions ne se mélangent pas

Le code équivalent diffère entre C# 4.0 et les versions antérieures.


En C# 4.0, c'est :

bool lockWasTaken = false;
var temp = obj;
try
{
    Monitor.Enter(temp, ref lockWasTaken);
    { corps }
}
finally
{
    if (lockWasTaken) Monitor.Exit(temp);
}

Cela repose sur le fait que Monitor.Enter établit de manière atomique le drapeau lorsque le verrou est pris.


Et auparavant, c'était :

var temp = obj;
Monitor.Enter(temp);
try
{
   corps
}
finally
{
    Monitor.Exit(temp);
}

Cela repose sur aucune exception n'étant lancée entre Monitor.Enter et le try. Je pense que dans le code de débogage, cette condition a été violée car le compilateur a inséré un NOP entre eux, rendant ainsi possible l'arrêt du thread entre eux.

0 votes

Comme je l'ai indiqué, le premier exemple est en C#4 et l'autre est ce que les versions précédentes utilisent.

0 votes

En tant que note annexe, C# via CLR mentionne une mise en garde concernant le mot-clé lock : il est souvent nécessaire de faire quelque chose pour restaurer l'état corrompu (si applicable) avant de libérer le verrou. Étant donné que le mot-clé lock ne nous permet pas de mettre des instructions dans le bloc catch, nous devrions envisager d'écrire la version longue try-catch-finally pour les routines non triviales.

5 votes

IMO restaurer l'état partagé est orthogonal au verrouillage/multithreading. Donc cela devrait être fait avec un try-catch/finally à l'intérieur du bloc lock.

55voto

Lukáš Novotný Points 5948

verrouiller est juste un raccourci pour Monitor.Enter avec essayer + enfin et Monitor.Exit. Utilisez l'instruction de verrouillage chaque fois que c'est suffisant - si vous avez besoin de quelque chose comme TryEnter, vous devrez utiliser Monitor.

29voto

Shekhar_Pro Points 10465

Une instruction de verrouillage est équivalente à :

Monitor.Enter(objet);
try
{
   // Votre code ici...
}
finally
{
   Monitor.Exit(objet);
}

Cependant, gardez à l'esprit que Monitor peut également Attendre() et Pulser(), ce qui est souvent utile dans des situations de multithreading complexes.

Mise à jour

Cependant, dans C# 4, son implémentation est différente :

bool lockWasTaken = false;
var temp = obj;
try 
{
     Monitor.Enter(temp, ref lockWasTaken); 
     // votre code
}
finally 
{ 
     if (lockWasTaken) 
             Monitor.Exit(temp); 
} 

Merci à CodeInChaos pour les commentaires et les liens

0 votes

En C#4, l'instruction lock est implémentée différemment. blogs.msdn.com/b/ericlippert/archive/2009/03/06/…

3voto

Borja Points 1558

La serrure et le comportement de base du moniteur (entrée + sortie) sont plus ou moins les mêmes, mais le moniteur offre plus d'options qui vous permettent davantage de possibilités de synchronisation.

La serrure est un raccourci et c'est l'option pour une utilisation de base.

Si vous avez besoin de plus de contrôle, le moniteur est la meilleure option. Vous pouvez utiliser Wait, TryEnter et Pulse, pour des utilisations avancées (comme les barrières, les sémaphores, etc.).

3voto

RobertoBr Points 1057

Tous deux sont la même chose. Le mot-clé lock est c sharp et utilise la classe Monitor.

http://msdn.microsoft.com/en-us/library/ms173179(v=vs.80).aspx

3 votes

Regardez msdn.microsoft.com/en-us/library/ms173179(v=vs.80).aspx "En fait, le mot-clé lock est implémenté avec la classe Monitor. Par exemple"

1 votes

La mise en œuvre sous-jacente de lock utilise Monitor mais ils ne sont pas la même chose, considérez les méthodes fournies par Monitor qui n'existent pas pour lock, et la manière dont vous pouvez verrouiller et déverrouiller dans des blocs de code séparés.

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