Qual'è la differenza tra lock e Mutex?


Risposte:


146

Un blocco è specifico per AppDomain, mentre Mutex per il sistema operativo consente di eseguire il blocco e la sincronizzazione tra processi (IPC).


95

lockè una parola chiave del compilatore, non una classe o un oggetto reali. È un involucro attorno alla funzionalità della Monitorclasse ed è progettato per rendere Monitorpiù facile lavorare con il caso comune.

Il Monitor(e la lockparola chiave) sono, come diceva Darin, limitati al AppDomain. Principalmente perché è necessario un riferimento a un indirizzo di memoria (nella forma di un oggetto istanziato) per gestire il "blocco" e mantenere l'identità delMonitor

La Mutex, d'altra parte, è un Net involucro attorno ad un costrutto sistema operativo, e può essere utilizzato per la sincronizzazione a livello di sistema, utilizzando stringa dati (anziché un puntatore ai dati) come identificatore. Due mutex che fanno riferimento a due stringhe in due indirizzi di memoria completamente diversi, ma con gli stessi dati , utilizzeranno effettivamente lo stesso mutex del sistema operativo.


54

A Mutexpuò essere locale in un processo o in tutto il sistema . MSDN :

I mutex sono di due tipi: mutex locali, che sono senza nome, e denominati mutex di sistema. Un mutex locale esiste solo all'interno del processo.

Inoltre, si dovrebbe prestare particolare attenzione - anche nella stessa pagina - quando si utilizza un mutex a livello di sistema su un sistema con Servizi terminal.

Una delle differenze tra Mutexe lockè che Mutexutilizza un costrutto a livello di kernel , quindi la sincronizzazione richiederà sempre almeno una transizione spaziale spazio-kernel dell'utente.

lock- questo è davvero un collegamento alla Monitorclasse , d'altra parte cerca di evitare l'allocazione delle risorse del kernel e la transizione al codice del kernel (ed è quindi più snella e più veloce - se si deve trovare un costrutto WinAPI che assomigli, sarebbe CriticalSection).

L'altra differenza è ciò che gli altri sottolineano: un nome Mutex può essere utilizzato in tutti i processi.

A meno che uno non abbia esigenze particolari o richieda la sincronizzazione tra i processi, è meglio attenersi a lock(aka Monitor) ˛

Esistono molte altre differenze "minori", come la gestione dell'abbandono, ecc.

Lo stesso si può dire di ReaderWriterLocke ReaderWriterLockSlimin 3.5, Semaphoree il nuovo SemaphoreSlimin .NET 4.0 ecc. È vero che queste ultime xxSlimclassi non possono essere usate come primitive di sincronizzazione a livello di sistema, ma non sono mai state pensate per - erano "solo" intese per essere più veloce e più attento alle risorse.


25

Uso un Mutex per verificare se ho già una copia dell'applicazione in esecuzione sullo stesso computer.

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);

8

Molto è già stato detto, ma per semplificare, ecco la mia opinione.

lock -> Semplice da usare, wrapper sul monitor, blocca i thread in un AppDomain.

senza nome mutex -> simile a lock tranne che l'ambito di blocco è più ed è attraverso AppDomain in un processo.

Nominato mutex -> l'ambito di blocco è persino più di un mutex senza nome ed è un processo trasversale in un sistema operativo.

Quindi ora ci sono opzioni, devi scegliere quella più adatta al tuo caso.


Come ho capito dalle risposte e dagli esempi di mutex qui msdn.microsoft.com/en-us/library/… : un mutex senza nome si comporta come un lucchetto. Tuttavia mutex.WaitOne (1000) ci dà la possibilità di timeout del blocco. D'altra parte, Monitor. TryEnter ci dà anche quella capacità. Come accennato, Mutex è un wrapper. Quindi userei un lucchetto o un Monitor invece di un mutex senza nome. Ma se è richiesto un blocco tra i processi, un mutex denominato è la strada da percorrere. Perfavore, correggimi se sbaglio.
Koray,

6

Mutex è un processo incrociato e ci sarà un classico esempio di non eseguire più di un'istanza di un'applicazione.

Il secondo esempio è che stai avendo un file e non vuoi che processi diversi accedano allo stesso file, puoi implementare un Mutex ma ricorda una cosa che Mutex è un sistema operativo a livello e non può essere usato tra due processi remoti.

Il blocco è un modo più semplice per proteggere la sezione del codice ed è specifico per dominio, è possibile sostituire il blocco con i monitor se si desidera una sincronizzazione più controllata.


1

Poche altre differenze minori che non sono state menzionate nelle risposte:

  1. Nel caso di utilizzo di blocchi, si può essere certi che il blocco verrà rilasciato quando si verifica un'eccezione all'interno del blocco del blocco.
    Questo perché il blocco utilizza monitor sotto il cofano ed è implementato in questo modo:

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

    Pertanto, in ogni caso, il blocco viene rilasciato e non è necessario rilasciarlo manualmente (come si farebbe per i mutex).

  2. Per i Lock, di solito usi un oggetto privato per bloccare (e dovresti usare ).
    Questo è fatto per molte ragioni. (Altre informazioni: vedi questa risposta e documentazione ufficiale ).

Pertanto, in caso di blocchi, non è possibile (ottenere accidentalmente) l'accesso all'oggetto bloccato dall'esterno e causare alcuni danni.
Ma nel caso di Mutex, puoi, poiché è comune avere un Mutex che è contrassegnato come pubblico e utilizzato da qualsiasi luogo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.