Apa itu mutex?

655

Mutex adalah konsep pemrograman yang sering digunakan untuk memecahkan masalah multi-threading. Pertanyaan saya kepada komunitas:

Apa itu mutex dan bagaimana Anda menggunakannya?

bmurphy1976
sumber
2
Inilah artikel bagus tentang perbedaannya: barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore
Adam Davis
Tutorial tentang mutex dapat membantu menjernihkan semuanya: stackoverflow.com/questions/4989451/mutex-example-tutorial
Nav
1
Mutex seperti kunci kamar mandi di sebuah pompa bensin, memastikan bahwa hanya satu orang yang dapat menggunakan kamar mandi pada suatu waktu DAN bahwa tidak ada orang lain yang dapat menggunakan toilet sampai penghuni saat ini selesai dan kunci dikembalikan.
jonschlinkert

Jawaban:

2154

Ketika saya mengadakan diskusi besar di tempat kerja, saya menggunakan ayam karet yang saya simpan di meja saya hanya untuk acara-acara seperti itu. Orang yang memegang ayam adalah satu-satunya orang yang diizinkan berbicara. Jika Anda tidak memegang ayam Anda tidak dapat berbicara. Anda hanya dapat menunjukkan bahwa Anda menginginkan ayam dan menunggu sampai Anda mendapatkannya sebelum berbicara. Setelah selesai berbicara, Anda dapat mengembalikan ayam ke moderator yang akan menyerahkannya kepada orang berikutnya untuk berbicara. Ini memastikan bahwa orang tidak saling berbicara, dan juga memiliki ruang untuk berbicara.

Ganti Ayam dengan Mutex dan orang dengan utas dan pada dasarnya Anda memiliki konsep mutex.

Tentu saja, tidak ada yang namanya karet mutex. Hanya ayam karet. Kucing saya pernah punya tikus karet, tetapi mereka memakannya.

Tentu saja, sebelum Anda menggunakan ayam karet, Anda perlu bertanya pada diri sendiri apakah Anda benar-benar membutuhkan 5 orang di satu kamar dan apakah itu tidak hanya lebih mudah dengan satu orang di ruangan itu sendiri melakukan semua pekerjaan. Sebenarnya, ini hanya memperluas analogi, tetapi Anda mendapatkan idenya.

Xetius
sumber
9
Jawaban yang bagus Mungkinkah diperdebatkan bahwa Mutex sebenarnya adalah aturan yang menghentikan ayam dilewatkan? dan ayam adalah hal yang Anda kunci?
SirYakalot
3
@ SirYakalot, maksud Anda ayam adalah sumber dayanya, dan moderator adalah mutex?
Owen
157
Ayam itu adalah mutex . Orang-orang yang membangun mu .. ayam adalah utas yang bersaing . Moderator adalah OS . Ketika orang meminta ayam, mereka melakukan permintaan kunci. Saat Anda memanggil mutex.lock (), utas Anda terhenti () dan membuat permintaan kunci ke OS. Ketika OS mendeteksi bahwa mutex dilepaskan dari utas, itu hanya memberikannya kepada Anda, dan mengunci () kembali - mutex sekarang milik Anda dan hanya milik Anda. Tidak ada orang lain yang bisa mencurinya, karena memanggil kunci () akan memblokirnya. Ada juga try_lock () yang akan memblokir dan mengembalikan true ketika mutex adalah milik Anda dan segera false jika mutex sedang digunakan.
Петър Петров
4
Kamu jenius. Bisakah Anda menggunakan metafora ayam karet untuk menjelaskan monitor juga?
Riccardo
98
Terkadang asal-usul beberapa konsep pemrograman tidak jelas. Seorang pemula mungkin bertanya-tanya mengapa semua orang berbicara tentang regex. Tidak jelas bahwa regex adalah kependekan dari [reg] ular [ex]. Demikian pula, mutex adalah kependekan dari [mut] ual [ex] clusion. Ini mungkin membuat makna istilah lebih mudah dicerna. @ TheSmurf ditautkan ke dalamnya dalam jawaban mereka, tetapi mungkin ada baiknya menambahkannya di sini untuk tujuan historis.
Dodzi Dzakuma
138

Mutex adalah bendera yang saling eksklusif. Ini bertindak sebagai penjaga gerbang ke bagian kode yang memungkinkan satu utas masuk dan memblokir akses ke yang lainnya. Ini memastikan bahwa kode yang dikontrol hanya akan terkena satu utas pada satu waktu. Pastikan untuk melepaskan mutex saat Anda selesai. :)

Craig
sumber
11
Mutex tidak ada hubungannya dengan bagian kode saja, itu melindungi beberapa sumber daya. Sumber daya itu mungkin merupakan segmen kode jika mutex hanya pernah digunakan di sekitar kode itu tetapi, begitu Anda mulai menggunakan mutex di beberapa tempat dalam kode Anda, penjelasan Anda gagal. Biasanya itu juga dapat digunakan untuk melindungi beberapa struktur data, yang dapat diakses dari banyak tempat dalam kode.
paxdiablo
73

Pengecualian Saling. Inilah entri Wikipedia di atasnya:

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

Inti dari mutex adalah untuk menyinkronkan dua utas. Ketika Anda memiliki dua utas yang mencoba mengakses satu sumber daya, pola umumnya adalah memiliki blok kode pertama yang mencoba akses untuk mengatur mutex sebelum memasukkan kode. Ketika blok kode kedua mencoba akses, ia melihat mutex diatur dan menunggu sampai blok kode pertama selesai (dan un-set mutex), kemudian melanjutkan.

Rincian spesifik tentang bagaimana ini dicapai jelas sangat bervariasi oleh bahasa pemrograman.

TheSmurf
sumber
65

Saat Anda memiliki aplikasi multi-utas, utas yang berbeda terkadang berbagi sumber daya yang sama, seperti variabel atau serupa. Sumber bersama ini sering tidak dapat diakses pada saat yang sama, sehingga diperlukan konstruksi untuk memastikan bahwa hanya satu utas yang menggunakan sumber daya itu pada satu waktu.

Konsep ini disebut "pengecualian bersama" (Mutex pendek), dan merupakan cara untuk memastikan bahwa hanya satu utas yang diperbolehkan di dalam area itu, menggunakan sumber daya itu dll.

Cara menggunakannya adalah bahasa tertentu, tetapi seringkali (jika tidak selalu) didasarkan pada sistem operasi mutex.

Beberapa bahasa tidak memerlukan konstruksi ini, karena paradigma, misalnya pemrograman fungsional (Haskell, ML adalah contoh yang baik).

Mats Fredriksson
sumber
26

Dalam C #, mutex yang umum digunakan adalah Monitor . Jenisnya adalah ' System.Threading.Monitor '. Ini juga dapat digunakan secara implisit melalui pernyataan ' kunci (Objek) '. Salah satu contoh penggunaannya adalah ketika membangun kelas Singleton.

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

Pernyataan kunci menggunakan objek kunci pribadi membuat bagian kritis. Memerlukan setiap utas untuk menunggu sampai yang sebelumnya selesai. Utas pertama akan masuk ke bagian dan menginisialisasi instance. Utas kedua akan menunggu, masuk ke bagian, dan mendapatkan instance yang diinisialisasi.

Jenis sinkronisasi anggota statis dapat menggunakan pernyataan kunci dengan cara yang sama.

Anthony Mastrean
sumber
1
Ini adalah jawaban yang bergantung pada implementasi. Juga, Di CS monitor berbeda dari mutex. Monitor memiliki mekanisme sinkronisasi tetapi mutex hanya mengunci barang itu sampai tidak lagi diperlukan. IDK tentang detail implementasi atau semantik C #, tapi saya pikir konteks pertanyaannya lebih luas
marcoslhc
25

Apa itu Mutex ?

Mutex (Faktanya, istilah mutex adalah singkatan dari mutual exclusion) yang juga dikenal sebagai spinlock adalah alat sinkronisasi paling sederhana yang digunakan untuk melindungi daerah kritis dan dengan demikian mencegah kondisi balapan. Itu adalah utas yang harus mendapatkan kunci sebelum masuk ke bagian kritis (Pada bagian kritis multi utas berbagi variabel yang sama, memperbarui tabel, menulis file, dan sebagainya), ia melepaskan kunci ketika meninggalkan bagian kritis.

Apa itu Kondisi Ras ?

Kondisi ras terjadi ketika dua utas atau lebih dapat mengakses data yang dibagikan dan mereka mencoba mengubahnya pada saat yang sama. Karena algoritme penjadwalan utas dapat bertukar antar utas kapan saja, Anda tidak tahu urutan upaya utas untuk mengakses data yang dibagikan. Oleh karena itu, hasil dari perubahan dalam data tergantung pada algoritma penjadwalan thread, yaitu kedua thread "balap" untuk mengakses / mengubah data.

Contoh kehidupan nyata:

Ketika saya mengadakan diskusi besar di tempat kerja, saya menggunakan ayam karet yang saya simpan di meja saya hanya untuk acara-acara seperti itu. Orang yang memegang ayam adalah satu-satunya orang yang diizinkan berbicara. Jika Anda tidak memegang ayam Anda tidak dapat berbicara. Anda hanya dapat menunjukkan bahwa Anda menginginkan ayam dan menunggu sampai Anda mendapatkannya sebelum berbicara. Setelah selesai berbicara, Anda dapat mengembalikan ayam ke moderator yang akan menyerahkannya kepada orang berikutnya untuk berbicara. Ini memastikan bahwa orang tidak saling berbicara, dan juga memiliki ruang untuk berbicara.

Ganti Ayam dengan Mutex dan orang dengan utas dan pada dasarnya Anda memiliki konsep mutex.

@Xetius

Penggunaan dalam C #:

Contoh ini menunjukkan bagaimana objek Mutex lokal digunakan untuk menyinkronkan akses ke sumber daya yang dilindungi. Karena setiap utas panggilan diblokir hingga memperoleh kepemilikan mutex, ia harus memanggil metode ReleaseMutex untuk melepaskan kepemilikan utas.

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

Referensi Referensi MSDN

habib
sumber
1
contoh yang sangat bagus
Siwei Shen 申思维
22

Ada beberapa jawaban hebat di sini, berikut ini analogi hebat lainnya untuk menjelaskan apa itu mutex :

Pertimbangkan toilet tunggal dengan kunci . Ketika seseorang masuk, mereka mengambil kunci dan toilet ditempati . Jika orang lain perlu menggunakan toilet, mereka harus menunggu dalam antrian . Ketika orang di toilet selesai , mereka meneruskan kunci ke orang berikutnya dalam antrian. Masuk akal, bukan?

Mengkonversi toilet dalam cerita ke sumber daya bersama , dan kunci untuk mutex . Mengambil kunci ke toilet (memperoleh kunci) memungkinkan Anda untuk menggunakannya. Jika tidak ada kunci (kunci terkunci) Anda harus menunggu. Ketika kunci dikembalikan oleh orang ( lepaskan kunci ), Anda bebas untuk mendapatkannya sekarang.

Chen A.
sumber
Tetapi contoh c # tidak mendukung dukungan pernyataan antrian Anda, "kirimkan kunci ke orang berikutnya dalam antrian". Contohnya menunjukkan tumpukan atau acak. 1, 2, & 3 semua meminta akses, dalam urutan itu. Pertama diizinkan masuk ke dalam kawasan lindung, dan kemudian tiga diizinkan. Antrian akan memberikannya ke yang kedua.
donvnielsen
Saya tidak merujuk implementasi konkret, atau bahasa pemrograman konkret. Contoh saya berkaitan dengan abstraksi mutex tingkat tinggi sebagai prinsip.
Chen A.
18

Untuk memahami MUTEX pada awalnya Anda perlu tahu apa itu "kondisi lomba" dan kemudian hanya Anda yang akan mengerti mengapa MUTEX diperlukan. Misalkan Anda memiliki program multi-threading dan Anda memiliki dua utas. Sekarang, Anda memiliki satu pekerjaan dalam antrian pekerjaan. Utas pertama akan memeriksa antrian pekerjaan dan setelah menemukan pekerjaan itu akan mulai mengeksekusinya. Utas kedua juga akan memeriksa antrian pekerjaan dan menemukan bahwa ada satu pekerjaan dalam antrian. Jadi, itu juga akan menetapkan penunjuk kerja yang sama. Jadi, sekarang apa yang terjadi, kedua utas menjalankan pekerjaan yang sama. Ini akan menyebabkan kesalahan segmentasi. Ini adalah contoh kondisi lomba.

Solusi untuk masalah ini adalah MUTEX. MUTEX adalah sejenis kunci yang mengunci satu utas pada satu waktu. Jika utas lain ingin menguncinya, utas itu diblokir.

Topik MUTEX dalam tautan file pdf ini benar-benar layak dibaca.

pengguna3751012
sumber
Dengan "topik MUTEX" Anda maksudkan bagian pada semaphores, karena contohnya adalah semaphore biner, kan?
Carl G
2
well a Mutex hanya semafor dengan nilai 1
marcoslhc
Apa nama buku bab yang Anda bagikan? Tolong
Omar Faroque Anik
@OmarFaroqueAnik buku yang dirujuk adalah Advanced Linux Programming oleh CodeSourcery LLC, yang diterbitkan oleh New Riders Publishing dan dapat diakses dari beranda domain tertaut.
RM
11

Mutex berguna dalam situasi di mana Anda perlu menegakkan akses eksklusif ke sumber daya di berbagai proses, di mana kunci biasa tidak akan membantu karena hanya berfungsi di seluruh utas.

18 jam
sumber
Apakah itu benar? Tidak akankah masing-masing proses membuat salinan muteks mereka sendiri?
Leon
0

Mutex: Mutex adalah singkatan dari Mut ual Ex clusion. Ini berarti pada suatu waktu satu proses / utas dapat masuk ke bagian kritis. Dalam pemrograman bersamaan di mana banyak utas / proses mencoba memperbarui sumber daya bersama (variabel apa pun, memori bersama, dll.) Dapat menyebabkan beberapa hasil yang tidak terduga. (Karena hasilnya tergantung pada utas / proses mana yang mendapatkan akses pertama).

Untuk menghindari hasil yang tidak terduga seperti itu, kami memerlukan beberapa mekanisme sinkronisasi, yang memastikan bahwa hanya satu utas / proses mendapatkan akses ke sumber daya tersebut pada satu waktu.

pthread library menyediakan dukungan untuk Mutex.

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

Ini adalah struktur untuk tipe data mutex yaitu pthread_mutex_t. Ketika mutex terkunci, __lock atur ke 1. Ketika itu tidak terkunci __lock atel ke 0.

Ini memastikan bahwa tidak ada dua proses / utas yang dapat mengakses bagian kritis pada saat yang sama.

Sandeep_black
sumber