Kapan kita harus menggunakan mutex dan kapan kita harus menggunakan semaphore

Jawaban:

92

Inilah cara saya mengingat kapan harus menggunakan apa -

Semaphore: Gunakan semaphore ketika Anda (thread) ingin tidur sampai beberapa thread lain memberitahu Anda untuk bangun. Semaphore 'down' terjadi di satu thread (produsen) dan semaphore 'up' (untuk semaphore yang sama) terjadi di thread lain (konsumen) misalnya: Dalam masalah produsen-konsumen, produsen ingin tidur sampai setidaknya satu slot buffer kosong - hanya thread konsumen dapat mengetahui saat slot buffer kosong.

Mutex: Gunakan mutex ketika Anda (utas) ingin mengeksekusi kode yang tidak boleh dijalankan oleh utas lain pada saat yang sama. Mutex 'turun' terjadi di satu utas dan mutex 'naik' harus terjadi di utas yang sama nanti. misal: Jika Anda menghapus node dari daftar tertaut global, Anda tidak ingin thread lain mengotak-atik pointer saat Anda menghapus node. Saat Anda memperoleh mutex dan sibuk menghapus node, jika utas lain mencoba mendapatkan mutex yang sama, utas akan ditidurkan sampai Anda melepaskan mutex tersebut.

Spinlock: Gunakan spinlock ketika Anda benar-benar ingin menggunakan mutex tetapi utas Anda tidak diizinkan untuk tidur. misalnya: Penangan interupsi dalam kernel OS tidak boleh tidur. Jika tidak, sistem akan membeku / macet. Jika Anda perlu memasukkan node ke daftar tertaut yang dibagikan secara global dari penangan interupsi, dapatkan spinlock - sisipkan node - rilis spinlock.

Annu Gogatya
sumber
1
menambahkan ke: semaphores dan mutex adalah dua cara untuk menyediakan sinkronisasi. semaphore, bisa lebih terkait dengan pensinyalan (misalnya skenario masalah produsen dan konsumen), dan mutex, bisa lebih terkait dengan mengizinkan akses ke satu per satu (beberapa permintaan untuk mengakses sumber daya bersama, tetapi hanya satu diberikan pada satu waktu). [artikel bagus: geeksforgeeks.org/mutex-vs-semaphore/]
parasrish
57

Mutex adalah objek pengecualian bersama, mirip dengan semaphore tetapi hanya mengizinkan satu loker pada satu waktu dan yang batasan kepemilikannya mungkin lebih ketat daripada semaphore.

Ini dapat dianggap setara dengan semafor hitung normal (dengan hitungan satu) dan persyaratan bahwa itu hanya dapat dilepaskan oleh utas yang sama yang menguncinya (a) .

Semaphore, di sisi lain, memiliki jumlah yang sewenang-wenang dan dapat dikunci oleh banyak loker secara bersamaan. Dan itu mungkin tidak memiliki persyaratan bahwa itu dirilis oleh utas yang sama yang mengklaimnya (tetapi, jika tidak, Anda harus dengan hati-hati melacak siapa yang saat ini bertanggung jawab untuk itu, seperti memori yang dialokasikan).

Jadi, jika Anda memiliki sejumlah contoh sumber daya (katakanlah tiga tape drive), Anda dapat menggunakan semaphore dengan hitungan 3. Perhatikan bahwa ini tidak memberi tahu Anda yang mana dari tape drive yang Anda miliki, hanya yang Anda miliki nomor tertentu.

Juga dengan semaphore, dimungkinkan untuk satu loker untuk mengunci beberapa contoh sumber daya, seperti untuk salinan tape-to-tape. Jika Anda memiliki satu sumber daya (misalnya lokasi memori yang tidak ingin Anda rusak), mutex lebih cocok.

Operasi yang setara adalah:

Counting semaphore          Mutual exclusion semaphore
--------------------------  --------------------------
  Claim/decrease (P)                  Lock
  Release/increase (V)                Unlock

Selain itu: jika Anda pernah bertanya-tanya tentang huruf-huruf aneh yang digunakan untuk mengklaim dan melepaskan semaphore, itu karena penemunya adalah orang Belanda. Probeer te verlagen artinya mencoba dan menurun sedangkan verhogen artinya bertambah.


(a) ... atau dapat dianggap sebagai sesuatu yang sama sekali berbeda dari semaphore, yang mungkin lebih aman mengingat penggunaannya yang hampir selalu berbeda.

paxdiablo
sumber
Oke, saya juga menemukan semafor biner. Kapan kita harus menggunakan binary semaphore dan kapan kita harus menggunakan mutex?
Karthik Balaguru
Secara konseptual, semafor biner adalah mutex, dan itu setara dengan semafor normal dengan satu hitungan. Mungkin ada perbedaan dalam implementasi konsep seperti efisiensi, atau kepemilikan sumber daya (dapat dilepaskan oleh orang lain selain penggugat, yang saya tidak setuju dengan BTW - sumber daya hanya boleh dilepaskan oleh utas yang mengklaimnya ).
paxdiablo
1
Perbedaan implementasi potensial lainnya adalah mutex rekursif. Karena hanya ada satu sumber daya, utas tunggal dapat diizinkan untuk menguncinya beberapa kali (asalkan juga melepaskannya berkali-kali). Ini tidak begitu mudah dengan sumber daya multi-instance karena Anda mungkin tidak tahu apakah thread ingin mengklaim instance lain atau instance yang sama lagi.
paxdiablo
1
Mereka memecahkan masalah tertentu. Fakta bahwa masalah yang mereka pecahkan adalah orang-orang yang tidak terlalu grok mutex, tidak boleh meremehkan solusinya :-)
paxdiablo
5
Mutex sama sekali berbeda dari semafor biner. Maaf, tetapi definisi ini salah
Peer Stritzinger
49

Sangat penting untuk memahami bahwa mutex bukanlah semaphore dengan hitungan 1!

Inilah alasan mengapa ada hal-hal seperti semaphore biner (yang sebenarnya adalah semaphore dengan hitungan 1).

Perbedaan antara Mutex dan Binary-Semaphore adalah prinsip kepemilikan:

Mutex diperoleh oleh tugas dan oleh karena itu juga harus dirilis oleh tugas yang sama. Hal ini memungkinkan untuk memperbaiki beberapa masalah dengan semaphore biner (Rilis rahasia, kebuntuan rekursif dan inversi prioritas).

Peringatan: Saya menulis "memungkinkan", jika dan bagaimana masalah ini diperbaiki tergantung pada implementasi OS.

Karena mutex harus dirilis oleh tugas yang sama, ini tidak terlalu baik untuk sinkronisasi tugas. Tetapi jika digabungkan dengan variabel kondisi Anda mendapatkan blok bangunan yang sangat kuat untuk membangun semua jenis primitif ipc.

Jadi rekomendasi saya adalah: jika Anda menerapkan mutex dengan rapi dan variabel kondisi (seperti dengan pthreads POSIX) gunakan ini.

Gunakan semaphore hanya jika mereka benar-benar sesuai dengan masalah yang Anda coba selesaikan, jangan mencoba membangun primitif lain (misalnya rw-locks dari semaphore, gunakan mutex dan variabel kondisi untuk ini)

Ada banyak kesalahpahaman tentang mutex dan semaphore. Penjelasan terbaik yang saya temukan sejauh ini ada di artikel 3-Bagian ini:

Mutex vs. Semaphores - Bagian 1: Semaphores

Mutex vs. Semaphores - Bagian 2: Mutex

Mutex vs. Semaphores - Bagian 3 (bagian terakhir): Masalah Pengecualian Bersama

Rekan Stritzinger
sumber
Url ke situs ini berisi karakter yang funky dan karenanya tidak berfungsi ... Saya sedang mengerjakannya
Peer Stritzinger
13

Meskipun jawaban @opaxdiablo benar-benar benar, saya ingin menunjukkan bahwa skenario penggunaan kedua hal tersebut sangat berbeda. Mutex digunakan untuk melindungi bagian kode agar tidak berjalan secara bersamaan, semaphore digunakan untuk satu utas untuk memberi sinyal agar utas lain berjalan.

/* Task 1 */
pthread_mutex_lock(mutex_thing);
    // Safely use shared resource
pthread_mutex_unlock(mutex_thing);



/* Task 2 */
pthread_mutex_lock(mutex_thing);
   // Safely use shared resource
pthread_mutex_unlock(mutex_thing); // unlock mutex

Skenario semaphore berbeda:

/* Task 1 - Producer */
sema_post(&sem);   // Send the signal

/* Task 2 - Consumer */
sema_wait(&sem);   // Wait for signal

Lihat http://www.netrino.com/node/202 untuk penjelasan lebih lanjut

Patrick Schlüter
sumber
2
Kamu benar. Bahkan jika Anda menggunakan semaphore dengan hitungan satu, Anda menyiratkan sesuatu tentang apa yang Anda lakukan daripada jika Anda menggunakan mutex.
Omnifarious
Saya tidak yakin saya setuju dengan itu, meskipun saya tidak begitu setuju sehingga saya akan merendahkan Anda :-) Anda mengatakan bahwa pola penggunaan semaphore adalah untuk memberi tahu utas tetapi itulah yang dilakukan mutex ketika ada utas lain yang menunggu di atasnya, dan apa yang semaphore tidak lakukan ketika tidak ada utas di sema_wait:-) Menurut pendapat saya, keduanya tentang sumber daya dan pemberitahuan yang diberikan ke utas lain adalah efek samping (sangat penting, kinerja-bijaksana) dari perlindungan.
paxdiablo
You say that the usage pattern of semaphores is to notify threadsSatu poin tentang memberi tahu utas. Anda dapat menelepon sem_postdari penangan sinyal dengan aman ( pubs.opengroup.org/onlinepubs/009695399/functions/… ) tetapi tidak disarankan untuk menelepon pthread_mutex_lockdan pthread_mutex_unlockdari penangan sinyal ( manpages.ubuntu.com/manpages/lucid/man3/… )
@paxdiablo: Ada satu perbedaan utama antara mutex binary semaphore ini adalah mempertahankan jumlah referensi. Mutex atau Anda dapat mengatakan mutex bersyarat apa pun tidak mempertahankan hitungan apa pun yang terkait dengan kunci sedangkan senpahore digunakan untuk mempertahankan hitungan. Jadi sem_wait dan sem_post akan mempertahankan hitungan.
Prak
9

Lihat "Contoh Toilet" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm :

Mutex:

Adalah kunci toilet. Satu orang dapat memiliki kunci - menempati toilet - pada saat itu. Setelah selesai, orang tersebut memberikan (membebaskan) kunci ke orang berikutnya dalam antrian.

Secara resmi: "Mutex biasanya digunakan untuk membuat serial akses ke bagian kode peserta ulang yang tidak dapat dijalankan secara bersamaan oleh lebih dari satu utas. Objek mutex hanya mengizinkan satu utas ke bagian terkontrol, memaksa utas lain yang mencoba mendapatkan akses ke bagian itu untuk menunggu hingga utas pertama keluar dari bagian itu. " Ref: Perpustakaan Pengembang Symbian

(Mutex sebenarnya adalah semaphore dengan nilai 1.)

Tiang sinyal:

Adalah jumlah kunci toilet identik gratis. Contoh, katakanlah kita memiliki empat toilet dengan kunci dan kunci yang identik. Jumlah semaphore - jumlah kunci - diatur ke 4 di awal (keempat toilet gratis), maka nilai hitungan berkurang saat orang masuk. Jika semua toilet penuh, mis. tidak ada kunci bebas yang tersisa, jumlah semaphore adalah 0. Sekarang, saat persamaan. satu orang meninggalkan toilet, semaphore dinaikkan menjadi 1 (satu kunci gratis), dan diberikan kepada orang berikutnya dalam antrian.

Secara resmi: "Semaphore membatasi jumlah pengguna secara bersamaan dari resource bersama hingga jumlah maksimum. Thread dapat meminta akses ke resource (mengurangi semaphore), dan dapat memberi sinyal bahwa mereka telah selesai menggunakan resource (menaikkan semaphore). " Ref: Perpustakaan Pengembang Symbian

dinding depan
sumber
7

Berusaha untuk tidak terdengar lucu, tapi tidak bisa menahan diri.

Pertanyaan Anda seharusnya apa perbedaan antara mutex dan semaphores? Dan untuk lebih tepatnya pertanyaannya adalah, 'apa hubungan antara mutex dan semaphores?'

(Saya akan menambahkan pertanyaan itu tetapi saya 100% yakin beberapa moderator yang terlalu bersemangat akan menutupnya sebagai duplikat tanpa memahami perbedaan antara perbedaan dan hubungan.)

Dalam terminologi objek kita dapat mengamati bahwa:

observasi.1 Semaphore berisi mutex

observasi.2 Mutex bukan semaphore dan semaphore bukan mutex.

Ada beberapa semaphore yang akan bertindak seolah-olah mutex, disebut binary semaphore, tetapi mereka TIDAK mutex.

Ada bahan khusus yang disebut Signaling (posix menggunakan condition_variable untuk nama itu), diperlukan untuk membuat Semaphore dari mutex. Anggap saja sebagai sumber pemberitahuan. Jika dua atau lebih utas berlangganan ke sumber pemberitahuan yang sama, maka dimungkinkan untuk mengirim mereka pesan ke SATU atau ke SEMUA, untuk bangun.

Mungkin ada satu atau lebih penghitung yang terkait dengan semaphore, yang dijaga oleh mutex. Skenario paling sederhana untuk semaphore, ada satu penghitung yang bisa berupa 0 atau 1.

Di sinilah kebingungan mengalir seperti hujan monsun.

Semaphore dengan penghitung yang bisa 0 atau 1 BUKAN mutex.

Mutex memiliki dua status (0,1) dan satu kepemilikan (tugas). Semaphore memiliki mutex, beberapa penghitung dan variabel kondisi.

Sekarang, gunakan imajinasi Anda, dan setiap kombinasi penggunaan penghitung dan kapan harus memberi sinyal dapat membuat satu jenis-Semaphore.

  1. Penghitung tunggal dengan nilai 0 atau 1 dan memberi sinyal ketika nilai pergi ke 1 DAN kemudian membuka salah satu orang yang menunggu sinyal == Semafor biner

  2. Penghitung tunggal dengan nilai 0 ke N dan memberi sinyal ketika nilai menjadi kurang dari N, dan mengunci / menunggu ketika nilai adalah N == Menghitung semaphore

  3. Penghitung tunggal dengan nilai 0 ke N dan memberi sinyal ketika nilai pergi ke N, dan mengunci / menunggu ketika nilai kurang dari N == Semafor penghalang (baik jika mereka tidak memanggilnya, maka seharusnya.)

Sekarang untuk pertanyaan Anda, kapan menggunakan apa. (ATAU pertanyaan yang lebih tepat version.3 kapan menggunakan mutex dan kapan menggunakan biner-semaphore, karena tidak ada perbandingan dengan non-binary-semaphore.) Gunakan mutex jika 1. Anda menginginkan perilaku yang disesuaikan, yang tidak disediakan oleh biner semaphore, seperti spin-lock atau fast-lock atau rekursif-lock. Anda biasanya dapat menyesuaikan mutex dengan atribut, tetapi menyesuaikan semaphore tidak lain adalah menulis semaphore baru. 2. Anda ingin primitif ringan ATAU lebih cepat

Gunakan semaphores, ketika apa yang Anda inginkan benar-benar disediakan olehnya.

Jika Anda tidak mengerti apa yang disediakan oleh implementasi binary-semaphore Anda, maka IMHO, gunakan mutex.

Dan terakhir membaca buku daripada hanya mengandalkan SO.

Ajeet Ganga
sumber
5

Saya pikir pertanyaannya adalah perbedaan antara mutex dan binary semaphore.

Mutex = Ini adalah mekanisme kunci kepemilikan, hanya utas yang memperoleh kunci yang dapat membuka kunci.

binary Semaphore = Ini lebih merupakan mekanisme sinyal, utas prioritas tinggi lainnya jika mau dapat memberi sinyal dan mengambil kunci.

Saurabh Sengar
sumber
5

Mutex adalah untuk melindungi sumber daya bersama.
Semaphore adalah untuk mengirimkan utas.

Mutex:
Bayangkan ada beberapa tiket untuk dijual. Kita dapat mensimulasikan kasus di mana banyak orang membeli tiket pada saat yang sama: setiap orang memiliki alur untuk membeli tiket. Jelas kita perlu menggunakan mutex untuk melindungi tiket karena itu adalah sumber daya bersama.


Semaphore:
Bayangkan kita perlu melakukan perhitungan seperti di bawah ini:

c = a + b;

Selain itu, kita membutuhkan fungsi geta()untuk menghitung a, fungsi getb()untuk menghitung bdan fungsi getc()untuk melakukan perhitungan c = a + b.

Jelas, kita tidak dapat melakukan c = a + bkecuali geta()dan getb()telah selesai.
Jika ketiga fungsi adalah tiga utas, kita perlu mengirimkan tiga utas.

int a, b, c;
void geta()
{
    a = calculatea();
    semaphore_increase();
}

void getb()
{
    b = calculateb();
    semaphore_increase();
}

void getc()
{
    semaphore_decrease();
    semaphore_decrease();
    c = a + b;
}

t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);

Dengan bantuan semaphore, kode di atas dapat memastikan bahwa t3tidak akan melakukan tugasnya sampai t1dan t2telah melakukan tugasnya.

Singkatnya, semaphore adalah membuat utas dieksekusi sebagai perintah logis sedangkan mutex adalah untuk melindungi sumber daya bersama.
Jadi mereka BUKAN hal yang sama meskipun beberapa orang selalu mengatakan bahwa mutex adalah semaphore khusus dengan nilai awal 1. Anda juga dapat mengatakan seperti ini, tetapi harap perhatikan bahwa mereka digunakan dalam kasus yang berbeda. Jangan mengganti satu per satu meskipun Anda bisa melakukannya.

Yves
sumber
Menjual tiket adalah contoh yang bagus. Contoh semaphore agak tidak jelas (bagi saya sih).
prayagupd
1
Contoh @prayagupd Semaphore adalah membuat utas dalam beberapa pesanan sedangkan menjual tiket tidak perlu pesanan apa pun. Jika ada tiga orang: a, b dan c. Ketika mereka datang untuk membeli tiket, kami sama sekali tidak peduli dengan urutan pembelian tiket. Namun, jika kita melakukan perhitungan seperti itu: x = getx(); y = gety(); z = x + y;Untuk beberapa alasan, kita menggunakan tiga utas untuk melakukan tiga hal, sekarang urutan utas sangat penting karena kita tidak dapat melakukannya x + ykecuali getxdan getytelah selesai. Singkatnya, semaphore digunakan ketika kita peduli dengan urutan eksekusi multi-threading.
Yves
kena kau. Kedengarannya mirip dengan penghalang . Saya dapat mengatakan bahwa tunggu sampai utas xdan yselesai, lalu hitung z = x + y. Saya tahu java memiliki CyclicBarrier. Juga, saya tidak yakin apakah saya bisa mengatakan mapreduceitu kasus penggunaan semaphore juga, karena saya tidak bisa reducesampai semua mapselesai.
prayagupd
@pengen Bisa dibilang begitu.
Yves
2

Semua jawaban di atas memiliki kualitas yang baik, tetapi yang ini hanya untuk dihafalkan.Nama Mutex berasal dari Mutually Exclusive sehingga Anda termotivasi untuk menganggap kunci mutex sebagai Saling Pengecualian antara dua seperti hanya satu pada satu waktu, dan jika saya memilikinya kamu hanya bisa memilikinya setelah aku merilisnya, sebaliknya kasus seperti itu tidak ada karena Semaphore hanya seperti sinyal lalu lintas (yang juga berarti kata Semaphore).

Nishant Sondhi
sumber
1

Seperti yang telah ditunjukkan, semaphore dengan hitungan satu sama dengan semaphore 'biner' yang sama dengan mutex.

Hal utama yang saya lihat semaphores dengan jumlah yang lebih besar dari yang digunakan adalah situasi produsen / konsumen di mana Anda memiliki antrian dengan ukuran tetap tertentu.

Anda memiliki dua semaphore. Semafor pertama awalnya diatur menjadi jumlah item dalam antrian dan semafor kedua diatur ke 0. Produser melakukan operasi P pada semafor pertama, menambahkan antrian. dan melakukan operasi V pada detik. Konsumen melakukan operasi P pada semafor kedua, menghapus dari antrian, dan kemudian melakukan operasi V pada semafor pertama.

Dengan cara ini, produsen diblokir setiap kali mengisi antrean, dan konsumen diblokir setiap kali antrean kosong.

Beraneka ragam
sumber
1

Mutex adalah kasus khusus dari sebuah semafor. Semaphore memungkinkan beberapa utas masuk ke bagian kritis. Saat membuat semaphore Anda menentukan bagaimana thread diperbolehkan di bagian kritis. Tentu saja kode Anda harus dapat menangani beberapa akses ke bagian penting ini.

Frode Akselsen
sumber
-1

Semafor biner dan Mutex berbeda. Dari perspektif OS, semafor biner dan semafor penghitungan diimplementasikan dengan cara yang sama dan semafor biner dapat memiliki nilai 0 atau 1.

Mutex -> Hanya dapat digunakan untuk satu dan satu-satunya tujuan pengecualian bersama untuk bagian kode yang penting.

Semaphore -> Dapat digunakan untuk memecahkan berbagai masalah. Sebuah semaphore biner dapat digunakan untuk pensinyalan dan juga memecahkan masalah pengecualian bersama. Ketika diinisialisasi ke 0 , itu memecahkan masalah pensinyalan dan ketika diinisialisasi ke 1 , itu memecahkan masalah pengecualian bersama .

Ketika jumlah resource lebih banyak dan perlu disinkronkan, kita dapat menggunakan semaphore penghitungan.

Di blog saya, saya telah membahas topik-topik ini secara rinci.

https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html

Kain
sumber