Kapan kita harus menggunakan mutex dan kapan kita harus menggunakan semaphore?
Kapan kita harus menggunakan mutex dan kapan kita harus menggunakan semaphore?
Jawaban:
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.
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.
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
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
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.
You say that the usage pattern of semaphores is to notify threads
Satu poin tentang memberi tahu utas. Anda dapat menelepon sem_post
dari penangan sinyal dengan aman ( pubs.opengroup.org/onlinepubs/009695399/functions/… ) tetapi tidak disarankan untuk menelepon pthread_mutex_lock
dan pthread_mutex_unlock
dari penangan sinyal ( manpages.ubuntu.com/manpages/lucid/man3/… )
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
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.
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
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
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.
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.
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 b
dan fungsi getc()
untuk melakukan perhitungan c = a + b
.
Jelas, kita tidak dapat melakukan c = a + b
kecuali 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 t3
tidak akan melakukan tugasnya sampai t1
dan t2
telah 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.
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 + y
kecuali getx
dan gety
telah selesai. Singkatnya, semaphore digunakan ketika kita peduli dengan urutan eksekusi multi-threading.
x
dan y
selesai, lalu hitung z = x + y
. Saya tahu java memiliki CyclicBarrier
. Juga, saya tidak yakin apakah saya bisa mengatakan mapreduce
itu kasus penggunaan semaphore juga, karena saya tidak bisa reduce
sampai semua map
selesai.
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).
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.
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.
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