Was ist der Unterschied zwischen Lock und Mutex?

128

Was ist der Unterschied zwischen Lock und Mutex? Warum können sie nicht austauschbar verwendet werden?

RAM
quelle

Antworten:

146

Eine Sperre ist spezifisch für die AppDomain, während Mutex für das Betriebssystem das Sperren und Synchronisieren zwischen Prozessen (IPC) ermöglicht.

Darin Dimitrov
quelle
95

lockist ein Compiler-Schlüsselwort, keine tatsächliche Klasse oder ein Objekt. Es ist ein Wrapper um die Funktionalität der MonitorKlasse und wurde entwickelt, um die MonitorArbeit mit dem allgemeinen Fall zu vereinfachen.

Die Monitor(und das lockSchlüsselwort) sind, wie Darin sagte, auf die beschränkt AppDomain. In erster Linie, weil ein Verweis auf eine Speicheradresse (in Form eines instanziierten Objekts) erforderlich ist, um die "Sperre" zu verwalten und die Identität der zu erhaltenMonitor

Das Mutexist andererseits ein .Net-Wrapper um ein Betriebssystemkonstrukt und kann für die systemweite Synchronisation verwendet werden, wobei String- Daten (anstelle eines Zeigers auf Daten) als Bezeichner verwendet werden. Zwei Mutexe, die auf zwei Zeichenfolgen in zwei völlig unterschiedlichen Speicheradressen verweisen, aber dieselben Daten haben , verwenden tatsächlich denselben Mutex des Betriebssystems.

Toby
quelle
53

A Mutexkann entweder prozesslokal oder systemweit sein . MSDN :

Es gibt zwei Arten von Mutexen: lokale Mutexe, die nicht benannt sind, und benannte Systemmutexe. Ein lokaler Mutex existiert nur in Ihrem Prozess.

Darüber hinaus sollte bei der Verwendung eines systemweiten Mutex auf einem System mit Terminaldiensten besondere Sorgfalt angewendet werden - auch auf derselben Seite beschrieben.

Einer der Unterschiede zwischen Mutexund lockbesteht darin, dass Mutexein Konstrukt auf Kernelebene verwendet wird , sodass für die Synchronisierung immer mindestens ein Übergang zwischen Benutzerbereich und Kernelbereich erforderlich ist.

lock- das ist wirklich eine Abkürzung zur MonitorKlasse , versucht andererseits zu vermeiden, Kernelressourcen zuzuweisen und auf Kernelcode umzusteigen (und ist daher schlanker und schneller - wenn man ein WinAPI-Konstrukt finden muss, das ihm ähnelt, wäre es CriticalSection).

Der andere Unterschied ist, worauf andere hinweisen: Ein Name Mutex kann prozessübergreifend verwendet werden.

Wenn man keine besonderen Bedürfnisse hat oder eine Synchronisation zwischen Prozessen benötigt, ist es einfach besser, sich daran zu halten lock(auch bekannt als)Monitor ) ˛ zu halten

Es gibt einige andere "geringfügige" Unterschiede, wie z. B. den Umgang mit dem Verlassen usw.

Das Gleiche gilt für ReaderWriterLockund ReaderWriterLockSlimin 3.5 Semaphoreund das Neue SemaphoreSlimin .NET 4.0 usw. Es ist richtig, dass die letzteren xxSlimKlassen nicht als systemweite Synchronisationsprimitive verwendet werden können, aber sie waren nie dazu gedacht - sie waren "nur" gemeint schneller und ressourcenschonender sein.

Andras Vass
quelle
25

Ich verwende einen Mutex, um zu überprüfen, ob bereits eine Kopie der Anwendung auf demselben Computer ausgeführt wird.

bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);

if (!firstInstance)
{
    //another copy of this application running 
}
else
{
    //run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
Jonathan
quelle
8

Es wurde bereits viel gesagt, aber um es einfach zu machen, hier ist meine Meinung.

lock -> Einfach zu verwenden, Wrapper auf dem Monitor, sperrt Threads in einer AppDomain.

unbenannter Mutex -> ähnlich wie Sperren, außer dass der Sperrbereich mehr ist und sich in einem Prozess über AppDomain erstreckt.

Benannter Mutex -> Sperrbereich ist sogar mehr als unbenannter Mutex und prozessübergreifend in einem Betriebssystem.

Jetzt sind also Optionen verfügbar. Sie müssen die auswählen, die am besten zu Ihrem Fall passt.

Prakash Tripathi
quelle
Wie ich aus den Antworten und den Beispielen für Mutex hier verstanden habe msdn.microsoft.com/en-us/library/… : Ein unbenannter Mutex fungiert als Sperre. Mutex.WaitOne (1000) gibt uns jedoch die Möglichkeit, das Zeitlimit für die Sperre zu überschreiten. Auf der anderen Seite bietet uns Monitor.TryEnter auch diese Fähigkeit. Wie bereits erwähnt, ist Mutex ein Wrapper. Ich würde also ein Schloss oder einen Monitor anstelle eines unbenannten Mutex verwenden. Wenn jedoch eine prozessübergreifende Sperre erforderlich ist, ist ein benannter Mutex der richtige Weg. Bitte korrigieren Sie mich, wenn ich falsch liege.
Koray
6

Mutex ist ein prozessübergreifender Prozess, und es wird ein klassisches Beispiel dafür geben, dass nicht mehr als eine Instanz einer Anwendung ausgeführt wird.

Das zweite Beispiel ist, dass Sie eine Datei haben und nicht möchten, dass unterschiedliche Prozesse auf dieselbe Datei zugreifen. Sie können einen Mutex implementieren, aber denken Sie daran, dass Mutex ein Betriebssystem ist und nicht zwischen zwei Remote-Prozessen verwendet werden kann.

Die Sperre ist der einfachste Weg, um einen Teil Ihres Codes zu schützen. Sie ist appdomänenspezifisch. Sie können die Sperre durch Monitore ersetzen, wenn Sie eine kontrollierte Synchronisation wünschen.

TalentTuner
quelle
1

Einige kleinere Unterschiede, die in den Antworten nicht erwähnt wurden:

  1. Im Fall von Sperren verwenden, können Sie sicher sein , dass die Sperre wird freigegeben , wenn eine Ausnahme innerhalb des Blockes des Schlosses geschieht.
    Das ist , weil die Sperre Anwendungen Monitore unter der Haube und implementiert diese Art und Weise:

     object __lockObj = x;
     bool __lockWasTaken = false;
     try
     {
         System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
         // Your code...
     }
     finally
     {
         if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
     }

    Auf jeden Fall wird die Sperre aufgehoben, und Sie müssen sie nicht manuell aufheben (wie bei den Mutexen).

  2. Für Sperren verwenden Sie normalerweise ein privates Objekt zum Sperren (und sollten es verwenden ).
    Dies geschieht aus vielen Gründen. (Weitere Informationen: siehe diese Antwort und offizielle Dokumentation ).

Im Falle von Schlössern können Sie also nicht (versehentlich) von außen auf das gesperrte Objekt zugreifen und Schäden verursachen.
Bei Mutex ist dies jedoch möglich, da es üblich ist, einen Mutex zu verwenden, der als öffentlich gekennzeichnet ist und von überall verwendet wird.

Nur Schatten
quelle