Lock ve Mutex arasındaki fark nedir?


Yanıtlar:


146

Bir kilit , AppDomain'e özeldir , İşletim Sistemine Mutex ise süreçler arası kilitleme ve senkronizasyon (IPC) gerçekleştirmenize izin verir.


95

lockbir derleyici anahtar sözcüktür, gerçek bir sınıf veya nesne değildir. MonitorSınıfın işlevselliği etrafında bir sarmalayıcıdır Monitorve genel durum için çalışmayı kolaylaştırmak için tasarlanmıştır .

Monitor(Ve lockDarin'in sınırlı olarak, sözü edilen anahtar) vardır AppDomain. Öncelikle, "kilidi" yönetmek ve kimliğini korumak için bir bellek adresine (somutlaştırılmış bir nesne biçiminde) bir referans gerektiği içinMonitor

MutexÖte yandan, bir işletim sistemi yapısı etrafında Net sarıcı ve dize kullanarak, sistem genelinde senkronizasyon için kullanılabilen veri kimliğinin olarak (veriler yerine bir işaretçisi). Tamamen farklı iki bellek adresinde iki dizgeye başvuran, ancak aynı verilere sahip olan iki muteks, aslında aynı işletim sistemi muteksini kullanacaktır.


54

A Mutex, bir süreç için yerel veya sistem genelinde olabilir . MSDN :

Muteksler iki tiptedir: adsız olan ve sistem muteksleri olarak adlandırılan yerel muteksler. Yerel bir muteks, yalnızca sizin sürecinizde vardır.

Ayrıca, Terminal Hizmetleri olan bir sistemde sistem çapında bir muteks kullanırken - aynı sayfada ayrıntıları da verilen - özel dikkat gösterilmelidir.

Arasındaki farklardan birisi Mutexve lockolduğunu Mutexbir kullanan çekirdek düzeyinde yapı senkronizasyon her zaman en azından bir kullanıcı alanı-çekirdek alanı geçişi gerektirecektir, bu yüzden.

lock- bu gerçekten Monitorsınıfa giden bir kısayoldur , diğer yandan çekirdek kaynaklarını tahsis etmekten ve çekirdek koduna geçmekten kaçınmaya çalışır (ve bu nedenle daha yalın ve daha hızlıdır - eğer benzeyen bir WinAPI yapısı bulmak gerekirse, olur CriticalSection).

Diğer fark, diğerlerinin işaret ettiği şeydir: bir isim Mutex , süreçler arasında kullanılabilir.

Kişinin özel ihtiyaçları olmadıkça veya işlemler arasında senkronizasyon gerektirmedikçe, lock(aka Monitor) ' ye bağlı kalmak daha iyidir ˛

Terk edilmenin nasıl ele alınacağı vb. Gibi birkaç başka "küçük" farklılık vardır.

3.5 için de aynısı söylenebilir ReaderWriterLockve .NET 4.0 vb. İçin de yenisi . İkinci sınıfların sistem çapında senkronizasyon ilkelleri olarak kullanılamayacağı doğrudur , ancak asla amaçlanmamıştır - "sadece" daha hızlı ve daha kaynak dostu olmak.ReaderWriterLockSlimSemaphoreSemaphoreSlimxxSlim


25

Aynı makinede çalışan uygulamanın bir kopyasına zaten sahip olup olmadığımı kontrol etmek için bir Mutex kullanıyorum.

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

Şimdiden çok şey söylendi, ancak basitleştirmek için işte benim alacağım.

lock -> Kullanımı basit, monitörde sarıcı, bir AppDomain'deki iş parçacıkları arasında kilitlenir.

adsız mutex -> kilitleme kapsamının daha fazla olması dışında kilide benzer ve bir işlemde AppDomain genelinde bulunur.

Adlandırılmış mutex -> kilitleme kapsamı, adlandırılmamış bir muteksten bile daha fazlasıdır ve bir işletim sistemindeki süreç boyunca geçerlidir.

Artık seçenekler var, durumunuza en uygun olanı seçmeniz gerekiyor.


Buradaki cevaplardan ve muteks örneklerinden anladığım gibi msdn.microsoft.com/en-us/library/… : Adsız bir muteks bir kilit gibi davranır. Ancak mutex.WaitOne (1000) bize kilidi zaman aşımına uğratma şansı verir. Öte yandan, Monitor. TryEnter da bize bu yeteneği veriyor. Bahsedildiği gibi Mutex bir paketleyicidir. Bu yüzden isimsiz bir muteks yerine bir kilit veya Monitör kullanırdım. Ancak süreçler arasında bir kilit olması gerekiyorsa, gidilecek yol adlandırılmış bir mutekstir. Yanlışım varsa lütfen düzelt.
Koray

6

Mutex bir çapraz işlemdir ve bir uygulamanın birden fazla örneğini çalıştırmamanın klasik bir örneği olacaktır.

İkinci örnek, bir dosyaya sahip olduğunuzu ve aynı dosyaya erişmek için farklı bir işlem istemediğinizi, bir Mutex uygulayabileceğinizi ancak bir şeyi unutmayın Mutex'in işletim sistemi çapında olduğunu ve iki uzak işlem arasında kullanılamayacağını unutmayın.

Kilit, kodunuzun bir bölümünü korumanın en basit yoludur ve uygulamaya özgüdür, daha kontrollü senkronizasyon istiyorsanız kilidi Moniters ile değiştirebilirsiniz.


1

Cevaplarda bahsedilmeyen birkaç küçük farklılık daha var:

  1. Kilitleri kullanılması durumunda, kilit olacaktır emin olabilirsiniz yayımlanan bir istisna kilidin bloğunun içinde gerçekleştiğinde.
    Kaputun altında kilit kullandığı izler ve uygulanan Bunun nedeni bu şekilde:

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

    Böylece, her durumda, kilit serbest bırakılır ve manuel olarak serbest bırakmanıza gerek yoktur (muteksler için yaptığınız gibi).

  2. Kilitler için, genellikle kilitlemek için özel bir nesne kullanırsınız (ve kullanmanız gerekir ).
    Bu birçok nedenden dolayı yapılır. (Daha fazla bilgi: bu yanıta ve resmi belgelere bakın ).

Yani kilitlenme durumunda kilitli nesneye dışarıdan (kazayla) erişemezsiniz ve bir miktar zarar veremezsiniz .
Ancak Mutex durumunda, herkese açık olarak işaretlenen ve her yerden kullanılan bir Mutex'e sahip olmak yaygın olduğu için yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.