Muteks nedir?


654

Mutex, çok iş parçacıklı sorunları çözmek için sıklıkla kullanılan bir programlama konseptidir. Topluma sorum:

Muteks nedir ve nasıl kullanılır?



Mutex hakkında bir eğitim, işleri temizlemenize yardımcı olabilir: stackoverflow.com/questions/4989451/mutex-example-tutorial
Nav

1
Muteks, bir benzin istasyonundaki banyo anahtarı gibidir, aynı anda yalnızca bir kişinin tuvaleti kullanabilmesini sağlar ve mevcut kişi bitene ve anahtar iade edilene kadar kimsenin tuvaleti kullanmamasını sağlar.
jonschlinkert

Yanıtlar:


2153

İş yerinde büyük bir ısıtmalı tartışma yaparken, masamda böyle durumlar için tuttuğum bir lastik tavuk kullanıyorum. Tavuğu tutan kişi konuşmasına izin verilen tek kişidir. Tavuğu tutmazsan konuşamazsın. Yalnızca tavuğu istediğinizi belirtebilir ve konuşmadan önce onu elde edene kadar bekleyebilirsiniz. Konuşmayı bitirdiğinizde, tavuğu konuşmak için bir sonraki kişiye verecek olan moderatöre geri verebilirsiniz. Bu, insanların birbirleriyle konuşmalarını ve aynı zamanda kendi konuşma alanlarına sahip olmalarını sağlar.

Tavuğu Mutex ve iplikli kişi ile değiştirin ve temel olarak bir muteks kavramına sahipsiniz.

Tabii ki, kauçuk bir muteks diye bir şey yoktur. Sadece lastik tavuk. Kedilerimin bir zamanlar lastik bir faresi vardı, ama yediler.

Tabii ki, kauçuk tavuğu kullanmadan önce, kendinize bir odada 5 kişiye gerçekten ihtiyacınız olup olmadığını sormanız gerekir ve sadece odadaki bir kişi ile tüm işi kendi başına yapmak daha kolay olmaz. Aslında, bu sadece benzetmeyi genişletiyor, ama fikri anlıyorsunuz.


9
Mükemmel cevap. Mutex'in aslında tavuğun geçmesini engelleyen kurallar olduğu söylenebilir mi? ve tavuk kilitlediğin şey mi?
SirYakalot

3
@SirYakalot, tavuğun kaynağı olduğunu ve moderatörün muteks olduğunu mu söylüyorsunuz?
Owen

156
Tavuk muteks . İnsanlar mu .. tavuk hoilding konu rekabet vardır . Moderatör işletim sistemidir . İnsanlar tavuğu talep ettiklerinde kilit isteği yaparlar. Mutex.lock () öğesini çağırdığınızda, iş parçacınız lock () içinde durur ve işletim sistemine bir kilit isteği yapar. İşletim sistemi, muteksin bir iş parçacığından serbest bırakıldığını algıladığında, yalnızca size verir ve lock () döndürür - muteks artık sizindir ve yalnızca sizindir. Başka kimse çalamaz, çünkü lock () çağrısı onu engelleyecektir. Mutex senin olduğunda bloke ve true döndürecek ve mutex kullanımdaysa hemen false olan try_lock () da vardır.
Петър Петров

4
Sen bir dahisin. Monitörleri açıklamak için kauçuk tavuk metaforunu da kullanabilir misiniz?
Riccardo

98
Bazen bazı programlama kavramlarının kökenleri belirsizdir. Bir acemi, herkesin neden regex hakkında konuştuğunu merak edebilir. Normal ifadenin [reg] ular [ex] baskısının kısa olduğu açık değildir. Benzer şekilde, muteks, olağan [ex] kümelenme için kısadır. Bu, terimin anlamını sindirmeyi kolaylaştırabilir. @Smurf cevaplarında ona bağlantı verdi, ancak tarihi amaçlar için buraya eklemek iyi olabilir.
Dodzi Dzakuma

137

Mutex, birbirini dışlayan bir bayraktır. Bir iş parçacığının içeri girmesine ve diğerlerine erişiminin engellenmesine izin veren bir kod bölümüne kapı koruyucu görevi görür. Bu, kontrol edilen kodun aynı anda yalnızca tek bir iş parçacığına çarpmasını sağlar. İşiniz bittiğinde muteksi serbest bıraktığınızdan emin olun. :)


10
Muteksin kendi başına bir kod bölümü ile ilgisi yoktur, bazı kaynakları korur . Eğer muteks yalnızca bu kodun çevresinde kullanılırsa, ancak muteksi kodunuzda birden çok yerde kullanmaya başladığınız anda bu kaynak bir kod segmenti olabilir, açıklamanız başarısız olur. Tipik olarak, kodun birçok yerinden erişilebilen bazı veri yapısını korumak için de kullanılabilir.
paxdiablo

72

Karşılıklı dışlama. İşte Wikipedia girişi:

http://en.wikipedia.org/wiki/Mutual_exclusion

Muteksin amacı iki iş parçacığını eşitlemektir. Tek bir kaynağa erişmeye çalışan iki iş parçacığınız olduğunda, genel desen, kodu girmeden önce muteksi ayarlamak için ilk kod bloğuna erişmeye çalışır. İkinci kod bloğu erişmeye çalıştığında, muteksin ayarlandığını görür ve ilk kod bloğu tamamlanıncaya kadar bekler (ve muteksi çıkarır), sonra devam eder.

Bunun nasıl yapıldığına dair spesifik detaylar, programlama diline göre büyük ölçüde değişir.


65

Çok iş parçacıklı bir uygulamanız olduğunda, farklı iş parçacıkları bazen değişken veya benzeri gibi ortak bir kaynağı paylaşır. Bu paylaşılan kaynağa genellikle aynı anda erişilemez, bu nedenle bu kaynağı aynı anda yalnızca bir iş parçacığının kullandığından emin olmak için bir yapıya ihtiyaç vardır.

Bu kavram "karşılıklı dışlama" (kısa Mutex) olarak adlandırılır ve bu kaynağı kullanarak o alanın içinde yalnızca bir iş parçacığına izin verilmesini sağlamanın bir yoludur.

Bunların nasıl kullanılacağı dile özgüdür, ancak genellikle (her zaman olmasa da) bir işletim sistemi muteksine dayanır.

Bazı diller bu yapıya ihtiyaç duymaz, örneğin paradigma, örneğin fonksiyonel programlama (Haskell, ML iyi örneklerdir).


26

C # 'da kullanılan ortak muteks Monitör'dür . Tür ' System.Threading.Monitor ' tür. Ayrıca ' lock (Object) ' deyimi üzerinden dolaylı olarak da kullanılabilir . Bunun kullanımına bir örnek, bir Singleton sınıfı oluştururken verilebilir.

private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
    lock(instanceLock)
    {
        if(instance == null)
        {
            instance = new MySingleton();
        }
        return instance;
    }
}

Özel kilit nesnesini kullanan lock deyimi kritik bir bölüm oluşturur. Her iş parçacığının bir önceki işin bitmesini beklemesini istemek İlk evre bölüme girecek ve örneği başlatacaktır. İkinci iş parçacığı bekleyecek, bölüme girecek ve başlatılan örneği alacaktır.

Statik bir elemanın her türlü senkronizasyonu lock deyimini benzer şekilde kullanabilir.


1
Bu uygulamaya bağlı bir cevaptır. Ayrıca, CS'de bir monitör muteksten farklıdır. Monitörler bir senkronizasyon mekanizmasına sahiptir, ancak muteks artık gerekli olana kadar şeyi kilitler. IDK uygulama ayrıntıları veya C # semantik hakkında, ancak sorunun bağlamı daha geniş olduğunu düşünüyorum
marcoslhc

24

Bir nedir dışlama ?

Spineks olarak da bilinen muteks (Aslında, muteks terimi karşılıklı dışlama için kısadır), kritik bölgeleri korumak ve böylece yarış koşullarını önlemek için kullanılan en basit senkronizasyon aracıdır. Bir iş parçacığı, kritik bir bölüme girmeden önce bir kilit almalıdır (Kritik bölümde çoklu iş parçacıkları ortak bir değişkeni paylaşır, bir tabloyu güncelleştirir, bir dosya yazar vb.), Kritik bölümden ayrıldığında kilidi serbest bırakır.

Bir nedir yarışı Durumu ?

İki veya daha fazla iş parçacığı paylaşılan verilere erişebildiğinde ve aynı anda değiştirmeye çalıştıklarında bir yarış durumu oluşur. İş parçacığı zamanlama algoritması her zaman iş parçacıkları arasında geçiş yapabildiği için, iş parçacıklarının paylaşılan verilere erişmeye çalışacağı sırayı bilmiyorsunuz. Bu nedenle, veri değişikliğinin sonucu, iplik programlama algoritmasına bağlıdır, yani her iki iplik de verilere erişmek / verileri değiştirmek için "yarışır".

Gerçek hayat örneği:

İş yerinde büyük bir ısıtmalı tartışma yaparken, masamda böyle durumlar için tuttuğum bir lastik tavuk kullanıyorum. Tavuğu tutan kişi konuşmasına izin verilen tek kişidir. Tavuğu tutmazsan konuşamazsın. Yalnızca tavuğu istediğinizi belirtebilir ve konuşmadan önce onu elde edene kadar bekleyebilirsiniz. Konuşmayı bitirdiğinizde, tavuğu konuşmak için bir sonraki kişiye verecek olan moderatöre geri verebilirsiniz. Bu, insanların birbirleriyle konuşmalarını ve aynı zamanda kendi konuşma alanlarına sahip olmalarını sağlar.

Tavuğu Mutex ve iplikli kişi ile değiştirin ve temel olarak bir muteks kavramına sahipsiniz.

@Xetius

C # 'de kullanım:

Bu örnek, korumalı bir kaynağa erişimi eşitlemek için yerel bir Mutex nesnesinin nasıl kullanıldığını gösterir. Her çağrı iş parçacığı mutex'in sahipliğini alana kadar engellendiğinden, iş parçacığının sahipliğini serbest bırakmak için ReleaseMutex yöntemini çağırmalıdır.

using System;
using System.Threading;

class Example
{
    // Create a new Mutex. The creating thread does not own the mutex.
    private static Mutex mut = new Mutex();
    private const int numIterations = 1;
    private const int numThreads = 3;

    static void Main()
    {
        // Create the threads that will use the protected resource.
        for(int i = 0; i < numThreads; i++)
        {
            Thread newThread = new Thread(new ThreadStart(ThreadProc));
            newThread.Name = String.Format("Thread{0}", i + 1);
            newThread.Start();
        }

        // The main thread exits, but the application continues to
        // run until all foreground threads have exited.
    }

    private static void ThreadProc()
    {
        for(int i = 0; i < numIterations; i++)
        {
            UseResource();
        }
    }

    // This method represents a resource that must be synchronized
    // so that only one thread at a time can enter.
    private static void UseResource()
    {
        // Wait until it is safe to enter.
        Console.WriteLine("{0} is requesting the mutex", 
                          Thread.CurrentThread.Name);
        mut.WaitOne();

        Console.WriteLine("{0} has entered the protected area", 
                          Thread.CurrentThread.Name);

        // Place code to access non-reentrant resources here.

        // Simulate some work.
        Thread.Sleep(500);

        Console.WriteLine("{0} is leaving the protected area", 
            Thread.CurrentThread.Name);

        // Release the Mutex.
        mut.ReleaseMutex();
        Console.WriteLine("{0} has released the mutex", 
            Thread.CurrentThread.Name);
    }
}
// The example displays output like the following:
//       Thread1 is requesting the mutex
//       Thread2 is requesting the mutex
//       Thread1 has entered the protected area
//       Thread3 is requesting the mutex
//       Thread1 is leaving the protected area
//       Thread1 has released the mutex
//       Thread3 has entered the protected area
//       Thread3 is leaving the protected area
//       Thread3 has released the mutex
//       Thread2 has entered the protected area
//       Thread2 is leaving the protected area
//       Thread2 has released the mutex

MSDN Başvuru Mutex


1
iyi bir örnek
Siwei Shen 申思维

22

Burada bazı harika cevaplar var, işte muteksin ne olduğunu açıklamak için başka bir harika benzetme :

Anahtarlı tekli tuvaleti düşünün . Birisi girdiğinde anahtarı alır ve tuvalet işgal edilir . Başka birinin tuvaleti kullanması gerekiyorsa, kuyrukta beklemesi gerekir . Tuvaletteki kişi bittiğinde , anahtarı sıradaki bir sonraki kişiye geçirirler. Mantıklı, değil mi?

Dönüştürme tuvalet bir hikayenin içinde paylaşılan kaynağın ve anahtarın bir karşı Muteksleri . Anahtarı tuvalete götürmek (bir kilit almak) onu kullanmanıza izin verir. Anahtar yoksa (kilit kilitli) beklemeniz gerekir. Anahtar kişi tarafından iade edildiğinde ( kilidi serbest bırakın ) şimdi almakta özgürsünüz.


Ancak c # örneği sıra iddianızı desteklemiyor, "anahtarı sıradaki bir sonraki kişiye ilet". Örnek bir yığın veya rasgele gösterilmektedir. 1, 2 ve 3'ün tümü bu sırayla erişim ister. İlk önce korunan alana, sonra üç tanesine izin verilir. Bir kuyruk bunu ikinciye verirdi.
donvnielsen

Hiçbir somut uygulamadan ya da somut programlama dilinden bahsetmiyordum. Örneğim ilke olarak muteksin yüksek düzeyde soyutlanması ile ilgilidir.
Chen

18

Önce MUTEX'i anlamak için "yarış koşulu" nun ne olduğunu bilmeniz gerekir ve sonra MUTEX'in neden gerekli olduğunu yalnızca siz anlarsınız. Çok iş parçacıklı bir programınız olduğunu ve iki iş parçacığınızın olduğunu varsayalım. Şimdi, iş kuyruğunda bir işiniz var. İlk iş parçacığı iş kuyruğunu kontrol eder ve işi bulduktan sonra yürütmeye başlar. İkinci iş parçacığı ayrıca iş kuyruğunu kontrol eder ve kuyrukta bir iş olduğunu bulur. Böylece, aynı iş işaretçisini de atayacaktır. Şimdi ne oluyor, her iki iş parçacığı da aynı işi yapıyor. Bu bir segmentasyon hatasına neden olacaktır. Bu bir yarış koşulu örneğidir.

Bu sorunun çözümü MUTEX'tir. MUTEX her seferinde bir dişi kilitleyen bir çeşit kilittir. Başka bir evre onu kilitlemek isterse, evre bloke olur.

Bu pdf dosya bağlantısındaki MUTEX konusu gerçekten okumaya değer.


"MUTEX konusu" ile semaforlar bölümü kastedildi, çünkü örnekleri ikili semaforlar, değil mi?
Carl G

2
iyi bir Mutex sadece 1 değeri olan bir semafor
marcoslhc

Paylaştığınız bölümün kitabının adı nedir? Please
Omar Faroque Anik

@OmarFaroqueAnik atıfta bulunulan kitap, New Riders Publishing tarafından yayınlanan ve bağlantılı alanın ana sayfasından erişilebilir olan CodeSourcery LLC tarafından Gelişmiş Linux Programlama'dır.
RMart

11

Muteksler, birden çok işlem boyunca bir kaynağa özel erişimi zorlamanız gerektiğinde yararlıdır, düzenli bir kilit yalnızca iş parçacıkları arasında çalıştığı için yardımcı olmaz.


Bu gerçekten doğru mu? Bireysel süreçler kendi muteks kopyalarını oluşturmayacak mı?
Leon

0

Mutex: Mutex Mut ual Ex anlamına gelir * ını. Bir seferde bir işlem / iş parçacığının kritik bölüme girebileceği anlamına gelir. Birden çok iş parçacığının / işlemin paylaşılan kaynağı güncellemeye çalıştığı eşzamanlı programlamada (herhangi bir değişken, paylaşılan bellek vb.) Beklenmedik sonuçlara yol açabilir. (Sonuç, hangi iş parçacığının / işlemin ilk erişimi alacağına bağlıdır).

Böyle beklenmedik bir sonuçtan kaçınmak için, bir seferde yalnızca bir iş parçacığının / işlemin bu tür bir kaynağa erişmesini sağlayan bazı senkronizasyon mekanizmasına ihtiyacımız var.

pthread kütüphanesi Mutex için destek sağlar.

typedef union
{
  struct __pthread_mutex_s
  {
    ***int __lock;***
    unsigned int __count;
    int __owner;
#ifdef __x86_64__
    unsigned int __nusers;
#endif
 int __kind;
#ifdef __x86_64__
    short __spins;
    short __elision;
    __pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV      1
# define __PTHREAD_SPINS             0, 0
#else
    unsigned int __nusers;
    __extension__ union
    {
      struct
      {
        short __espins;
        short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS         { 0, 0 }
      } __elision_data;
      __pthread_slist_t __list;
    };
#endif

Bu muteks veri tipinin yapısıdır, yani pthread_mutex_t. Muteks kilitlendiğinde, __lock 1 olarak ayarlanır. Kilidi açıldığında __lock 0 olarak ayarlanır.

Bu, kritik işleme aynı anda iki işlemin / iş parçacığının erişememesini sağlar.

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.