Mereka secara semantik sama, tetapi dalam praktiknya Anda akan melihat perbedaan aneh (terutama pada Windows).
Michael Foukarakis
5
@Michael Foukarakis: Apa perbedaan anehnya?
Philipp
2
Kurasa aneh bukan ekspresi yang benar. Mutex juga mendukung kepemilikan dan terkadang masuk kembali. Ini adalah kasus di Windows. Selain itu, semafor di Windows diterapkan di atas objek Acara, namun, saya tidak yakin tentang implikasi praktis dari ini.
@ philipxy Baik menyembunyikan 'rn' di tempat 'm'.
Mooncrater
Jawaban:
691
Mereka BUKAN hal yang sama. Mereka digunakan untuk berbagai tujuan!
Sementara kedua jenis semaphore memiliki keadaan penuh / kosong dan menggunakan API yang sama, penggunaannya sangat berbeda.
Semaphores Pengecualian Mutual Semaphores Pengecualian
Mutual digunakan untuk melindungi sumber daya bersama (struktur data, file, dll.).
Semafor Mutex "dimiliki" oleh tugas yang mengambilnya. Jika Tugas B mencoba untuk memberikan mutasi mutex yang saat ini dipegang oleh Tugas A, panggilan Tugas B akan mengembalikan kesalahan dan gagal.
Mutex selalu menggunakan urutan berikut:
- Semtake
- Bagian penting
- SemGive
Ini adalah contoh sederhana:
Utas A Utas B
Ambil Mutex
mengakses data
... Ambil Mutex <== Akan diblokir
...
Berikan data akses Mutex <== Buka blokir
...
Berikan Mutex
Binary Semaphore
Binary Semaphore menjawab pertanyaan yang sangat berbeda:
Tugas B sedang menunggu menunggu sesuatu terjadi (misalnya sensor sedang tersandung).
Trip Sensor dan Interupsi Layanan Rutin berjalan. Perlu memberi tahu tugas perjalanan.
Tugas B harus dijalankan dan mengambil tindakan yang sesuai untuk trip sensor. Kemudian kembali untuk menunggu.
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
Perhatikan bahwa dengan semaphore biner, tidak apa-apa bagi B untuk mengambil semaphore dan A untuk memberikannya.
Sekali lagi, semaphore biner TIDAK melindungi sumber daya dari akses. Tindakan Memberi dan Mengambil semafor secara fundamental dipisahkan.
Biasanya tidak masuk akal untuk tugas yang sama untuk memberi dan menerima semaphore biner yang sama.
Bukankah mutex lebih baik dari semaphore biner? Karena tidak masuk akal jika seseorang melepaskan kunci yang sebenarnya tidak dipegangnya.
Pacerier
111
Mereka memiliki tujuan berbeda. Mutex adalah untuk akses eksklusif ke sumber daya. Semaphore Binary harus digunakan untuk Sinkronisasi (yaitu "Hai Seseorang! Ini terjadi!"). "Pemberi" Biner hanya memberi tahu siapa pun "pengambil" bahwa apa yang mereka tunggu terjadi.
Benoit
5
@Pacerier Anda mengacaukan tujuannya. Mutex dimaksudkan melindungi wilayah kritis. Anda benar, tidak masuk akal untuk menggunakan Binary Semaphore. Saya akan memperbarui jawaban untuk menjelaskan tujuan masing-masing.
Benoit
4
@ Beneno Jadi dapatkah kita mengatakan bahwa Mutex Digunakan untuk atomisitas dan Binary Semaphore untuk perspektif Pemesanan karena Tugas B akan menunggu Tugas A untuk memberi sinyal pelepasan kunci yang secara inheren memastikan pemesanan operasi pada strurcture data?
abhi
1
@abhi Itu cara yang bagus untuk melihatnya untuk Mutex. Namun, tergantung pada OS, Anda dapat memiliki lebih dari satu penerima menunggu di semaphore biner. Dalam hal ini, hanya satu dari klien yang akan mendapatkan sem biner. Yang lain akan menunggu yang berikutnya. Apakah urutan penerimaan diketahui atau dijamin? Tergantung pada OS.
Benoit
446
Sebuah mutex bisa dilepaskan hanya dengan benang yang telah diperoleh itu .
Sebuah semaphore biner dapat mengisyaratkan oleh benang (atau proses).
jadi semaphore lebih cocok untuk beberapa masalah sinkronisasi seperti produsen-konsumen.
Pada Windows, semaphore biner lebih seperti objek acara daripada mutex.
Mutex can be released only by thread that had acquired it- Saya baru saja mencoba dengan program sederhana berbasis pthread_mutex, utas dapat membuka kunci mutex yang dikunci di utas utama
daisy
15
@ warl0ck Sesuai halaman manual pthread_mutex_lock linux.die.net/man/3/pthread_mutex_lock : "Jika tipe mutex adalah PTHREAD_MUTEX_ERRORCHECK, maka pengecekan error harus disediakan .... Jika sebuah thread mencoba membuka kunci mutex yang dimilikinya. tidak dikunci atau mutex yang tidak dikunci, kesalahan akan dikembalikan. "
amit
47
@ warl0ck Silakan lihat stackoverflow.com/a/5492499/385064 'Pthreads memiliki 3 jenis mutex: Mutex cepat, mutex rekursif, dan mutex memeriksa kesalahan. Anda menggunakan mutex cepat yang, karena alasan kinerja, tidak akan memeriksa kesalahan ini. Jika Anda menggunakan kesalahan memeriksa mutex di Linux Anda akan menemukan Anda mendapatkan hasil yang Anda harapkan. '
FrostNovaZzz
1
Dalam kode kami, kami telah menggunakan mutex juga untuk keperluan sinkronisasi. Thread yang mengunci mutex lagi mencoba untuk mengunci mutex. Kemudian ia pergi ke keadaan diblokir. Apa yang telah kita lihat adalah bahwa kita dapat membuka kunci ini dari utas lain. Dengan demikian mencapai sinkronisasi antara keduanya. Kami hanya menggunakan standar posix. Jadi perbedaan utama yang terletak antara mutex dan binary semaphore tampaknya kabur.
achoora
1
@achoora Saya setuju bahwa adalah salah untuk mengkhususkan semaphore untuk sinkronisasi. Sebenarnya semua mutex, binary-semaphore, barrier, pipeline adalah pola yang berbeda untuk sinkronisasi. Dalam perspektif desain, mutex lebih seperti pola negara di mana algoritma yang dipilih oleh negara dapat mengubah negara. Biner-semaphore lebih seperti pola strategi di mana algoritma eksternal dapat mengubah keadaan dan akhirnya algoritma / strategi yang dipilih untuk dijalankan.
Merupakan 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 dari kode peserta ulang yang tidak dapat dieksekusi secara bersamaan oleh lebih dari satu utas. Objek muteks hanya memungkinkan satu utas ke dalam bagian yang dikontrol, memaksa utas lain yang berupaya mendapatkan akses ke bagian itu untuk menunggu sampai utas pertama telah keluar dari bagian itu. " Ref: Perpustakaan Pengembang Symbian
(Mutex benar-benar semaphore dengan nilai 1.)
Tiang sinyal:
Apakah jumlah kunci toilet identik gratis. Contoh, misalkan kita memiliki empat toilet dengan kunci dan kunci yang identik. Hitungan semaphore - hitungan kunci - diatur ke 4 di awal (keempat toilet gratis), maka nilai hitungan dikurangi ketika orang masuk. Jika semua toilet penuh, yaitu. tidak ada kunci gratis yang tersisa, jumlah semaphore adalah 0. Sekarang, ketika eq. satu orang meninggalkan toilet, semaphore dinaikkan menjadi 1 (satu kunci gratis), dan diberikan kepada orang berikutnya dalam antrian.
Secara resmi: "Semafor membatasi jumlah pengguna simultan sumber daya bersama hingga jumlah maksimum. Utas dapat meminta akses ke sumber daya (mengurangi semafor), dan dapat memberi sinyal bahwa mereka telah selesai menggunakan sumber daya (menambah semafor). " Ref: Perpustakaan Pengembang Symbian
... tapi ini tentang mutex vs penghitungan semaphore. Pertanyaannya adalah tentang biner.
Roman Nikitchenko
24
Meskipun apa yang dikatakan oleh david adalah benar, tetapi BUKAN jawaban untuk pertanyaan yang diajukan. Jawaban Mladen Jankovic adalah jawaban untuk pertanyaan yang diajukan, di mana poin dibuat untuk membedakan "binary-semaphore" vs "mutex".
Ajeet Ganga
13
Sayangnya, jawaban yang salah ini memiliki lebih banyak suara daripada jawaban terbaik oleh @Benoit
NeonGlow
6
Jawaban ini menyesatkan. Harus dibandingkan dengan Binary Semaphore.
Hemanth
3
Ini juga menunjukkan masalah dengan menggunakan semaphore penghitungan untuk melindungi sumber daya bersama: jika kunci memang identik, dan toilet tidak dikunci menggunakan kunci, dan tidak ada mekanisme lain untuk mendistribusikan penggunaan bilik, maka: (1) yang pertama pengguna membuka kunci, masuk dan mulai menggunakan bilik pertama. (2) pengguna berikutnya membuka, masuk dan mulai menggunakan bilik pertama ...
Mutex ini mirip dengan prinsip-prinsip biner semaphore dengan satu perbedaan signifikan: prinsip kepemilikan. Kepemilikan adalah konsep sederhana bahwa ketika suatu tugas mengunci (memperoleh) sebuah mutex hanya ia dapat membuka (melepaskan) itu. Jika suatu tugas mencoba membuka kunci mutex yang belum dikunci (maka tidak dimiliki sendiri) maka terjadi kesalahan dan, yang paling penting, mutex tidak terbuka. Jika objek pengecualian bersama tidak memiliki kepemilikan, maka tidak relevan dengan apa yang disebutnya, itu bukan mutex.
Terima kasih atas tautannya, penjelasannya sangat bagus. Tautan telah berubah: feabhas.com/blog/2009/09/… (Gunakan <Sebelumnya dan Selanjutnya> untuk menavigasi ke dua artikel lainnya.
Aaron H.
@ Harun Saya memperbaiki tautannya
Hakim Maygarden
Catatan - kurangnya kepemilikan juga mencegah sistem operasi untuk bekerja di sekitar inversi prioritas. Untuk alasan ini, saya biasanya menggunakan variabel kondisi sebagai lawan dari semafor untuk arsitektur produsen / konsumen.
kgriff
1
Memberi +1 tautan artikel yang bagus. Artikel terbaik yang menjelaskan semaphore dan mutex dengan "apa-apa-itu" dan "apa-apa-apa" komputasi.llnl.gov/tutorials/pthreads Saya telah menggunakan artikel ini sebagai referensi di belakang layar saya, yang secara teknis menjelaskan semua tentang mutex / conditional dan konstruksi lainnya dibangun di atas mereka seperti semaphore / penghalang / pembaca-penulis, tetapi tidak eksplisit dan ringkas tentang masalah yang dihadapi dengan konstruksi. Singkatnya itu adalah referensi. :)
Ajeet Ganga
lebih mudah dipahami daripada jawaban lainnya.
BinaryTreeee
101
Karena tidak ada jawaban di atas yang menghilangkan kebingungan, berikut adalah salah satu yang membersihkan kebingungan saya.
Sebenarnya, mutex adalah mekanisme penguncian yang digunakan untuk menyinkronkan akses ke sumber daya. Hanya satu tugas (dapat berupa utas atau proses berdasarkan abstraksi OS) yang dapat memperoleh mutex. Ini berarti akan ada kepemilikan yang terkait dengan mutex, dan hanya pemilik yang dapat melepaskan kunci (mutex).
Semaphore adalah mekanisme pensinyalan ("Saya sudah selesai, Anda bisa melanjutkan" semacam sinyal). Misalnya, jika Anda mendengarkan lagu (menganggapnya sebagai satu tugas) di ponsel Anda dan pada saat yang sama teman Anda memanggil Anda, interupsi akan dipicu ketika interrupt service routine (ISR) akan memberi sinyal tugas pemrosesan panggilan untuk bangun. .
mutex memungkinkan serialisasi akses ke sumber daya yang diberikan yaitu beberapa utas menunggu kunci, satu per satu dan seperti yang dikatakan sebelumnya, utas memiliki kunci sampai selesai: hanya utas khusus ini yang dapat membuka kunci.
semaphore biner adalah penghitung dengan nilai 0 dan 1: tugas yang memblokirnya sampai tugas apa pun melakukan sem_post. Semaphore mengiklankan bahwa sumber daya tersedia, dan menyediakan mekanisme untuk menunggu sampai diberi sinyal sebagai tersedia.
Dengan demikian orang dapat melihat mutex sebagai token yang diteruskan dari satu tugas ke tugas lain dan semafor sebagai lampu merah lalu lintas (ini memberi sinyal seseorang bahwa ia dapat melanjutkan).
Pada tingkat teoretis, mereka tidak berbeda secara semantik. Anda dapat menerapkan mutex menggunakan semaphores atau sebaliknya (lihat di sini untuk contoh). Dalam praktiknya, implementasinya berbeda dan mereka menawarkan layanan yang sedikit berbeda.
Perbedaan praktis (dalam hal layanan sistem di sekitarnya) adalah bahwa penerapan mutex ditujukan untuk menjadi mekanisme sinkronisasi yang lebih ringan. Dalam bahasa oracle, mutex dikenal sebagai kait dan semaphore dikenal sebagai menunggu .
Pada level terendah, mereka menggunakan semacam uji atom dan mekanisme pengaturan . Ini membaca nilai saat ini dari lokasi memori, menghitung semacam persyaratan dan menulis nilai di lokasi itu dalam satu instruksi yang tidak dapat diinterupsi . Ini berarti Anda dapat memperoleh mutex dan menguji untuk melihat apakah ada orang lain yang memilikinya sebelum Anda.
Implementasi mutex yang khas memiliki proses atau utas yang melaksanakan instruksi tes dan set dan mengevaluasi apakah ada hal lain yang telah mengatur mutex. Poin kunci di sini adalah bahwa tidak ada interaksi dengan penjadwal , jadi kami tidak tahu (dan tidak peduli) siapa yang telah mengatur kunci. Kemudian kita menyerah irisan waktu kita dan mencobanya lagi ketika tugas dijadwalkan ulang atau menjalankan spin-lock . Spin lock adalah algoritme seperti:
Count down from 5000:
i. Execute the test-and-set instruction
ii. If the mutex is clear, we have acquired it in the previous instruction
so we can exit the loop
iii. When we get to zero, give up our time slice.
Ketika kami telah selesai menjalankan kode kami yang dilindungi (dikenal sebagai bagian kritis ) kami hanya menetapkan nilai mutex ke nol atau apa pun artinya 'jelas.' Jika beberapa tugas berusaha untuk mendapatkan mutex, tugas berikutnya yang dijadwalkan setelah mutex dilepaskan akan mendapatkan akses ke sumber daya. Biasanya Anda akan menggunakan mutex untuk mengontrol sumber daya yang disinkronkan di mana akses eksklusif hanya diperlukan untuk waktu yang sangat singkat, biasanya untuk membuat pembaruan ke struktur data bersama.
Semaphore adalah struktur data yang disinkronkan (biasanya menggunakan mutex) yang memiliki hitungan dan beberapa pembungkus panggilan sistem yang berinteraksi dengan scheduler sedikit lebih dalam daripada perpustakaan mutex. Semafor bertambah dan dikurangi dan digunakan untuk memblokir tugas sampai hal lain siap. Lihat Masalah Produsen / Konsumen untuk contoh sederhana ini. Semaphore diinisialisasi ke beberapa nilai - semaphore biner hanyalah kasus khusus di mana semaphore diinisialisasi ke 1. Posting ke semaphore memiliki efek membangunkan proses menunggu.
Algoritma semaphore dasar terlihat seperti:
(somewhere in the program startup)
Initialise the semaphore to its start-up value.
Acquiring a semaphore
i. (synchronised) Attempt to decrement the semaphore value
ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.
Posting a semaphore
i. (synchronised) Increment the semaphore value
ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.
iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.
Dalam kasus semaphore biner, perbedaan praktis utama antara keduanya adalah sifat layanan sistem yang mengelilingi struktur data aktual.
EDIT: Seperti yang ditunjukkan oleh evan dengan benar, spinlocks akan memperlambat mesin prosesor tunggal. Anda hanya akan menggunakan spinlock pada kotak multi-prosesor karena pada satu prosesor proses memegang mutex tidak akan mengatur ulang saat tugas lain sedang berjalan. Spinlocks hanya berguna pada arsitektur multi-prosesor.
Saya tidak berpikir itu adalah praktik umum untuk mutex diimplementasikan dengan spinlocks. Pada mesin Uni-proc ini akan sangat mengerikan untuk kinerja.
Evan Teran
Biasanya Anda hanya akan menggunakan spinlocks pada sistem multi-prosesor.
ConcernedOfTunbridgeWells
Bahkan di SMP, setelah berputar beberapa kali Anda kembali ke tidur / bangun yang dibantu OS. (misal, futexpanggilan sistem Linux ada untuk membantu implementasi mutex / semaphore userspace latensi rendah. en.wikipedia.org/wiki/Futex ) Di jalur cepat tanpa pertengkaran, atau jika sumber daya tersedia segera, Anda tidak akan pernah memiliki overhead dari panggilan sistem. Tetapi Anda tidak menghabiskan lebih dari beberapa mikro-sibuk-menunggu (berputar). Menyetel parameter putaran balik dan tunggu adalah tergantung pada perangkat keras dan beban kerja, tetapi pustaka standar biasanya memiliki pilihan yang masuk akal.
Peter Cordes
19
Meskipun mutex & semaphore digunakan sebagai primitif sinkronisasi, ada perbedaan besar di antara mereka. Dalam hal mutex, hanya utas yang mengunci atau mendapatkan mutex yang dapat membukanya. Dalam kasus semaphore, utas yang menunggu semafor dapat ditandai oleh utas yang berbeda. Beberapa sistem operasi mendukung penggunaan mutex & semaphores antar proses. Biasanya penggunaan dibuat di memori bersama.
"dapat ditandai oleh utas berbeda" apa artinya memberi contoh.
Myanju
15
Mutex: Misalkan kita memiliki utas bagian kritis T1 ingin mengaksesnya lalu mengikuti langkah-langkah di bawah ini. T1:
Mengunci
Gunakan Bagian Kritis
Membuka kunci
Binary semaphore: Ini bekerja berdasarkan signalling wait dan signal. tunggu, turunkan nilai "s" satu per satu biasanya nilai "s" diinisialisasi dengan nilai "1", sinyal meningkatkan nilai "s" satu per satu. jika nilai "s" adalah 1 berarti tidak ada yang menggunakan bagian kritis, ketika nilai 0 berarti bagian kritis digunakan. misalkan utas T2 menggunakan bagian kritis lalu mengikuti langkah-langkah di bawah ini. T2:
tunggu // nilai awalnya adalah satu setelah memanggil tunggu nilainya berkurang satu yaitu 0
Gunakan bagian kritis
signal // sekarang nilainya dinaikkan dan menjadi 1
Perbedaan utama antara Mutex dan Binary semaphore adalah Mutext jika thread mengunci bagian kritis maka harus membuka bagian kritis tidak ada thread lain yang bisa membukanya, tetapi dalam kasus Binary semaphore jika salah satu thread mengunci bagian kritis menggunakan fungsi menunggu maka nilai dari s menjadi "0" dan tidak ada yang dapat mengaksesnya sampai nilai "s" menjadi 1 tetapi anggaplah beberapa sinyal panggilan lain maka nilai "s" menjadi 1 dan memungkinkan fungsi lain untuk menggunakan bagian kritis. karenanya dalam semaphore Biner thread tidak memiliki kepemilikan.
Pada Windows, ada dua perbedaan antara mutex dan semaphore biner:
Mutex hanya dapat dirilis oleh utas yang memiliki kepemilikan, yaitu utas yang sebelumnya disebut fungsi Tunggu, (atau yang mengambil kepemilikan saat membuatnya). Semaphore dapat dirilis oleh utas apa pun.
Utas dapat memanggil fungsi tunggu berulang kali pada mutex tanpa memblokir. Namun, jika Anda memanggil fungsi tunggu dua kali pada semaphore biner tanpa melepaskan semaphore di antaranya, utas akan memblokir.
Anda jelas menggunakan mutex untuk mengunci data dalam satu utas yang diakses oleh utas lain pada saat yang sama. Asumsikan bahwa Anda baru saja menelepon lock()dan sedang dalam proses mengakses data. Ini berarti bahwa Anda tidak mengharapkan utas lainnya (atau contoh lain dari kode-utas yang sama) untuk mengakses data yang sama dikunci oleh mutex yang sama. Yaitu, jika itu adalah kode-thread yang sama dijalankan pada instance thread yang berbeda, tekan kunci, makalock()harus memblokir aliran kontrol di sana. Ini berlaku untuk utas yang menggunakan utas-kode berbeda, yang juga mengakses data yang sama dan yang juga dikunci oleh mutex yang sama. Dalam hal ini, Anda masih dalam proses mengakses data dan Anda dapat mengambil, katakanlah, 15 detik untuk mencapai pembukaan kunci mutex (sehingga utas lain yang diblokir di kunci mutex akan membuka blokir dan akan memungkinkan kontrol untuk akses data). Apakah Anda dengan biaya berapa pun membiarkan utas lain membuka kunci mutex yang sama, dan pada gilirannya, mengizinkan utas yang sudah menunggu (memblokir) dalam kunci mutex untuk membuka blokir dan mengakses data? Semoga Anda mengerti apa yang saya katakan di sini? Sesuai, disepakati definisi universal !,
dengan "mutex" ini tidak bisa terjadi. Tidak ada utas lain yang dapat membuka kunci pada utas Anda
dengan "binary-semaphore" ini bisa terjadi. Utas lainnya dapat membuka kunci di utas Anda
Jadi, jika Anda sangat khusus menggunakan binary-semaphore daripada mutex, maka Anda harus sangat berhati-hati dalam “pelingkupan” kunci dan pembatalannya. Maksud saya, setiap aliran kontrol yang mengenai setiap kunci harus mengenai panggilan pembuka, juga tidak boleh ada "pembukaan pertama", melainkan harus selalu "kunci pertama".
Beberapa artikel mengatakan bahwa "semaphore biner dan mutex sama" atau "Semaphore dengan nilai 1 adalah mutex" tetapi perbedaan dasarnya adalah Mutex hanya dapat dilepaskan oleh utas yang telah mengakuisisi, sementara Anda dapat memberi sinyal semafor dari utas lain
Poin-Poin Utama:
• Sebuah utas dapat memperoleh lebih dari satu kunci (Mutex).
• Sebuah mutex dapat dikunci lebih dari sekali hanya jika itu adalah mutex rekursif, di sini mengunci dan membuka kunci untuk mutex harus sama
• Jika utas yang sudah mengunci mutex, mencoba untuk mengunci mutex lagi, itu akan masuk ke dalam daftar tunggu mutex itu, yang mengakibatkan kebuntuan.
• Semaphore biner dan mutex serupa tetapi tidak sama.
• Mutex adalah operasi yang mahal karena protokol perlindungan yang terkait dengannya.
• Tujuan utama mutex adalah mencapai akses atom atau mengunci sumber daya
Sebuah mutex mengontrol akses ke sumber daya bersama tunggal. Ini memberikan operasi untuk memperoleh () akses ke sumber daya itu dan melepaskan () ketika selesai.
Sebuah Semaphore mengontrol akses ke kolam renang bersama sumber daya. Ini menyediakan operasi untuk Tunggu () sampai salah satu sumber daya di kumpulan tersedia, dan Sinyal () ketika diberikan kembali ke kumpulan.
Ketika jumlah sumber daya yang dilindungi Semaphore lebih besar dari 1, itu disebut Counting Semaphore . Ketika mengontrol satu sumber daya, itu disebut Boolean Semaphore . Semaphore boolean setara dengan mutex.
Jadi Semaphore adalah abstraksi level yang lebih tinggi daripada Mutex. Mutex dapat diimplementasikan menggunakan Semaphore tetapi tidak sebaliknya.
Pertanyaan yang dimodifikasi adalah - Apa perbedaan antara A mutex dan "binary" semaphore di "Linux"?
Jawab: Berikut adalah perbedaannya - i) Lingkup - Ruang lingkup mutex berada dalam ruang alamat proses yang telah membuatnya dan digunakan untuk sinkronisasi utas. Sedangkan semaphore dapat digunakan melintasi ruang proses dan karenanya dapat digunakan untuk sinkronisasi antarproses.
ii) Mutex lebih ringan dan lebih cepat dari semaphore. Futex bahkan lebih cepat.
iii) Mutex dapat diperoleh dengan utas yang sama berhasil beberapa kali dengan syarat harus melepaskannya beberapa kali. Utas lain yang mencoba mengakuisisi akan diblokir. Sedangkan dalam kasus semaphore jika proses yang sama mencoba untuk mendapatkannya kembali itu blok karena hanya dapat diperoleh satu kali.
Perbedaan antara Binary Semaphore dan Mutex: KEPEMILIKAN:
Semaphores dapat diisyaratkan (diposting) bahkan dari pemilik yang tidak aktif. Ini berarti Anda cukup memposting dari utas lain, meskipun Anda bukan pemiliknya.
Semaphore adalah properti publik dalam proses, Ini dapat dengan mudah diposting oleh utas bukan pemilik. Harap Tandai perbedaan ini dalam huruf BOLD, ini sangat berarti.
Terlepas dari kenyataan bahwa mutex memiliki pemilik, kedua objek dapat dioptimalkan untuk penggunaan yang berbeda. Mutex dirancang untuk diadakan hanya untuk waktu yang singkat; melanggar ini dapat menyebabkan kinerja yang buruk dan penjadwalan yang tidak adil. Misalnya, utas berjalan mungkin diizinkan untuk mendapatkan mutex, meskipun utas lain sudah diblokir di situ. Semafor dapat memberikan lebih banyak keadilan, atau keadilan dapat dipaksa menggunakan beberapa variabel kondisi.
Dalam kasus-kasus tertentu mana keadilan dijamin untuk semafor tetapi tidak untuk mutex?
curiousguy
1
POSIX memiliki persyaratan tertentu yang benang harus dibangunkan oleh sem_post()untuk SCHED_FIFOdan SCHED_RR(kedua ini tidak default): prioritas thread tertinggi, dan jika ada beberapa dengan prioritas yang sama, benang yang telah menunggu terpanjang. OpenSolaris mengikuti aturan FIFO ini sampai taraf tertentu bahkan untuk penjadwalan normal. Untuk glibc dan FreeBSD, membuka kunci mutex sederhana (yaitu bukan prioritas memproteksi atau mewarisi prioritas) dan memposting semafor pada dasarnya sama, menandai objek sebagai tidak terkunci dan kemudian, jika mungkin ada utas menunggu, memanggil kernel untuk membangunkannya.
Jilles
4
Di windows perbedaannya adalah seperti di bawah ini.
MUTEX: proses yang berhasil dijalankan menunggu harus mengeksekusi sinyal dan sebaliknya. SEMINFOR BINARY: Berbagai proses dapat menjalankan operasi menunggu atau memberi sinyal pada semaphore.
Sementara semaphore biner dapat digunakan sebagai mutex, mutex adalah use-case yang lebih spesifik, dalam hal itu hanya proses yang mengunci mutex yang seharusnya membuka kuncinya. Batasan kepemilikan ini memungkinkan untuk memberikan perlindungan terhadap:
Pelepasan tak disengaja
Kebuntuan Rekursif
Deadlock Tugas Kematian
Kendala ini tidak selalu ada karena mereka menurunkan kecepatan. Selama pengembangan kode Anda, Anda dapat mengaktifkan pemeriksaan ini sementara.
mis. Anda dapat mengaktifkan atribut Pemeriksaan kesalahan di mutex Anda. Kesalahan memeriksa mutexes kembali EDEADLKjika Anda mencoba untuk mengunci yang sama dua kali danEPERM jika Anda membuka kunci mutex yang bukan milik Anda.
Konsepnya jelas bagi saya setelah membahas posting di atas. Tapi ada beberapa pertanyaan yang tersisa. Jadi, saya menulis kode kecil ini.
Ketika kami mencoba memberikan semafor tanpa mengambilnya, ia berhasil melewatinya. Tetapi, ketika Anda mencoba memberikan mutex tanpa mengambilnya, itu gagal. Saya menguji ini pada platform Windows. Aktifkan USE_MUTEX untuk menjalankan kode yang sama menggunakan MUTEX.
#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1
DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );
HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;
int main(void)
{
#ifdef USE_MUTEX
ghMutex = CreateMutex( NULL, FALSE, NULL);
if (ghMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 1;
}
#else
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
#endif
// Create thread 1.
Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL)
{
printf("Create first thread problem \n");
return 1;
}
/* sleep for 5 seconds **/
Sleep(5 * 1000);
/*Create thread 2 */
Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);
if ( Handle_Of_Thread_2 == NULL)
{
printf("Create second thread problem \n");
return 1;
}
// Sleep for 20 seconds
Sleep(20 * 1000);
printf("Out of the program \n");
return 0;
}
int my_critical_section_code(HANDLE thread_handle)
{
#ifdef USE_MUTEX
if(thread_handle == Handle_Of_Thread_1)
{
/* get the lock */
WaitForSingleObject(ghMutex, INFINITE);
printf("Thread 1 holding the mutex \n");
}
#else
/* get the semaphore */
if(thread_handle == Handle_Of_Thread_1)
{
WaitForSingleObject(ghSemaphore, INFINITE);
printf("Thread 1 holding semaphore \n");
}
#endif
if(thread_handle == Handle_Of_Thread_1)
{
/* sleep for 10 seconds */
Sleep(10 * 1000);
#ifdef USE_MUTEX
printf("Thread 1 about to release mutex \n");
#else
printf("Thread 1 about to release semaphore \n");
#endif
}
else
{
/* sleep for 3 secconds */
Sleep(3 * 1000);
}
#ifdef USE_MUTEX
/* release the lock*/
if(!ReleaseMutex(ghMutex))
{
printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
}
#else
if (!ReleaseSemaphore(ghSemaphore,1,NULL) )
{
printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
}
#endif
return 0;
}
DWORD WINAPI Thread_no_1( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_1);
return 0;
}
DWORD WINAPI Thread_no_2( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_2);
return 0;
}
Fakta bahwa semaphore memungkinkan Anda memberi sinyal "itu dilakukan dengan menggunakan sumber daya", meskipun tidak pernah memiliki sumber daya, membuat saya berpikir ada hubungan yang sangat longgar antara memiliki dan memberi sinyal dalam kasus semafor.
Jika Anda membaca jawaban yang lain, jelas bahwa konsep "kepemilikan" hanya masuk akal dengan mutex, bukan semaphore. Semafor dapat digunakan untuk hal-hal seperti utas agar utas lain tahu bahwa pemrosesan sebagian data telah dilakukan; hasil siap dibaca.
Peter Cordes
2
Mutex digunakan untuk melindungi kode sensitif dan data, semaphore digunakan untuk sinkronisasi. Anda juga dapat memiliki penggunaan praktis dengan melindungi kode sensitif, tetapi mungkin ada risiko yang melepaskan perlindungan oleh utas lainnya dengan operasi V.Jadi, yang utama perbedaan antara bi-semaphore dan mutex adalah kepemilikan. Misalnya dengan toilet, Mutex seperti itu orang bisa masuk toilet dan mengunci pintu, tidak ada orang lain yang bisa masuk sampai pria itu keluar, bi-semaphore seperti itu yang bisa masuk toilet dan mengunci pintu, tetapi orang lain bisa masuk dengan meminta administrator untuk membuka pintu, itu konyol.
Mutex biasanya digunakan untuk membuat serialisasi akses ke bagian kode re-entrant yang tidak dapat dieksekusi secara bersamaan oleh lebih dari satu utas. Objek mutex hanya memungkinkan satu utas masuk ke bagian yang dikontrol, memaksa utas lain yang berupaya mendapatkan akses ke bagian itu untuk menunggu sampai utas pertama keluar dari bagian itu. Penggunaan yang benar dari mutex adalah untuk melindungi sumber daya bersama yang dapat memiliki bahaya. efek samping yang tidak diinginkan. Dua tugas RTOS yang beroperasi pada prioritas yang berbeda dan berkoordinasi melalui mutex, menciptakan peluang untuk inversi prioritas . Mutex bekerja di ruang pengguna .
Tiang sinyal
Semaphore adalah mekanisme pensinyalan. Semaphore membatasi jumlah pengguna simultan dari sumber daya bersama hingga jumlah maksimum. Thread dapat meminta akses ke sumber daya (menurunkan semaphore) dan dapat memberi sinyal bahwa mereka telah selesai menggunakan sumber daya (incrementing the semaphore). Ini memungkinkan sejumlah utas untuk mengakses sumber daya bersama. Penggunaan semafor yang benar adalah untuk pensinyalan dari satu tugas ke tugas lainnya. Memori juga dapat digunakan untuk memberi sinyal dari interrupt service routine (ISR) ke suatu tugas. Signaling semaphore adalah perilaku RTOS yang tidak menghalangi dan dengan demikian ISR aman. Karena teknik ini menghilangkan kebutuhan yang rawan kesalahan untuk menonaktifkan interupsi pada tingkat tugas. Ini bekerja di ruang kernel .
Jawabannya mungkin tergantung pada OS target. Sebagai contoh, setidaknya satu implementasi RTOS yang saya kenal akan memungkinkan beberapa operasi "get" berurutan terhadap satu OS mutex, asalkan semuanya dari dalam konteks utas yang sama. Beberapa get harus diganti dengan jumlah put yang sama sebelum thread lain diizinkan untuk mendapatkan mutex. Ini berbeda dari semaphore biner, yang hanya dapat satu kali diizinkan pada satu waktu, terlepas dari konteks utas.
Gagasan di balik jenis mutex ini adalah bahwa Anda melindungi objek dengan hanya mengizinkan satu konteks untuk memodifikasi data pada suatu waktu. Bahkan jika utas mendapatkan mutex dan kemudian memanggil fungsi yang lebih lanjut memodifikasi objek (dan mendapat / menempatkan pelindung mutex di sekitar operasinya sendiri), operasi harus tetap aman karena semuanya terjadi di bawah utas tunggal.
{
mutexGet(); // Other threads can no longer get the mutex.
// Make changes to the protected object.
// ...
objectModify(); // Also gets/puts the mutex. Only allowed from this thread context.
// Make more changes to the protected object.
// ...
mutexPut(); // Finally allows other threads to get the mutex.
}
Tentu saja, ketika menggunakan fitur ini, Anda harus yakin bahwa semua akses dalam satu utas benar-benar aman!
Saya tidak yakin seberapa umum pendekatan ini, atau apakah itu berlaku di luar sistem yang saya kenal. Untuk contoh mutex semacam ini, lihat ThreadX RTOS.
Jenis mutex yang Anda bicarakan disebut "recursive mutex" dan harus dihindari karena lambat dan cenderung mempromosikan desain yang buruk: (lihat David Butenhof: zaval.org/resources/library/butenhof1.html )
gaspard
Sepakat. Pada OS khusus ini, saya menggunakan layanan mutex di mana saya ingin memperjelas bahwa kodenya adalah untuk "pengecualian bersama" dan bukan penghitungan referensi, tetapi saya tidak menggunakan fitur rekursif karena takut akan kehancuran yang buruk. Namun, dalam konteks pertanyaan, ini adalah perbedaan penting antara "mutex" dan "semaphore biner."
Casey Barker
1
Mutex memiliki kepemilikan, tidak seperti semaphore. Meskipun setiap utas, dalam lingkup mutex, bisa mendapatkan mutex yang tidak dikunci dan mengunci akses ke bagian kode yang sama, hanya utas yang mengunci mutex yang akan membukanya .
apa itu kepemilikan? Maksud Anda konteks yang memperoleh mutex hanya dapat membatalkannya ??
Raulp
1
Seperti yang telah disebutkan oleh banyak orang di sini, sebuah mutex digunakan untuk melindungi bagian penting dari kode (bagian kritis AKA.) Anda akan memperoleh mutex (kunci), memasuki bagian kritis, dan melepaskan mutex (membuka) semua di utas yang sama .
Saat menggunakan semaphore, Anda dapat membuat utas menunggu di semafor (katakan utas A), hingga utas lainnya (misalkan utas B) menyelesaikan tugas apa pun, lalu setel Semafor untuk utas A untuk menghentikan penantian, dan melanjutkan tugasnya.
Sampai saat ini, satu-satunya kunci tidur di kernel adalah semaphore. Sebagian besar pengguna semaphore membuat semaphore dengan hitungan satu dan memperlakukan mereka sebagai kunci pengecualian bersama - versi tidur dari kunci-kunci. Sayangnya, semaphore agak generik dan tidak memaksakan batasan penggunaan. Ini membuatnya berguna untuk mengelola akses eksklusif dalam situasi yang tidak jelas, seperti tarian rumit antara kernel dan ruang pengguna. Tetapi itu juga berarti bahwa penguncian yang lebih sederhana lebih sulit untuk dilakukan, dan kurangnya aturan yang ditegakkan membuat segala jenis debugging otomatis atau penegakan kendala menjadi tidak mungkin. Mencari kunci tidur yang lebih sederhana, pengembang kernel memperkenalkan mutex. Ya, seperti yang biasa Anda lakukan, itu adalah nama yang membingungkan. Mari kita perjelas. Istilah “mutex” adalah nama generik untuk merujuk pada kunci tidur apa pun yang memberlakukan saling pengecualian, seperti semaphore dengan hitungan penggunaan satu. Dalam kernel Linux baru-baru ini, kata benda yang tepat "mutex" sekarang juga merupakan jenis kunci penguncian khusus yang menerapkan saling pengecualian. Artinya, mutex adalah mutex.
Kesederhanaan dan efisiensi dari mutex berasal dari kendala tambahan yang dikenakan pada penggunanya melebihi dan melebihi apa yang semafor butuhkan. Tidak seperti semaphore, yang menerapkan perilaku paling dasar sesuai dengan desain asli Dijkstra, mutex memiliki kasus penggunaan yang lebih ketat, lebih sempit: n Hanya satu tugas yang dapat menahan mutex pada suatu waktu. Artinya, jumlah penggunaan pada mutex selalu satu.
Siapa pun yang mengunci mutex harus membukanya. Artinya, Anda tidak dapat mengunci mutex dalam satu konteks dan kemudian membukanya di lain. Ini berarti bahwa mutex tidak cocok untuk sinkronisasi yang lebih rumit antara kernel dan ruang pengguna. Namun, sebagian besar kasus penggunaan, mengunci dan membuka kunci dengan rapi dari konteks yang sama.
Kunci rekursi dan buka kunci tidak diizinkan. Artinya, Anda tidak bisa secara rekursif mendapatkan mutex yang sama, dan Anda tidak bisa membuka kunci mutex yang tidak terkunci.
Suatu proses tidak dapat keluar saat memegang mutex.
Mutex tidak dapat diperoleh oleh pengendali interupsi atau setengah bagian bawah, bahkan dengan mutex_trylock ().
Mutex hanya dapat dikelola melalui API resmi: Mutual harus diinisialisasi melalui metode yang dijelaskan dalam bagian ini dan tidak dapat disalin, diinisialisasi dengan tangan, atau diinisialisasi ulang.
[1] Pengembangan Kernel Linux, Edisi Ketiga Robert Love
Saya pikir sebagian besar jawaban di sini membingungkan terutama yang mengatakan bahwa mutex dapat dirilis hanya oleh proses yang menahannya tetapi semaphore dapat ditandai oleh proses. Baris di atas agak kabur dalam hal semafor. Untuk memahami kita harus tahu bahwa ada dua jenis semaphore satu disebut berhitung semaphore dan yang lainnya disebut binary semaphore. Dalam penghitungan semaphore menangani akses ke n jumlah sumber daya di mana n dapat didefinisikan sebelum penggunaan. Setiap semaphore memiliki variabel jumlah, yang menjaga jumlah jumlah sumber daya yang digunakan, awalnya, diatur ke n. Setiap proses yang ingin menggunakan sumber daya melakukan operasi menunggu () pada semaphore (dengan demikian mengurangi jumlah). Ketika suatu proses melepaskan sumber daya, ia melakukan operasi rilis () (menambah jumlah). Saat hitungan menjadi 0, semua sumber daya digunakan. Setelah itu, proses menunggu hingga hitungan menjadi lebih dari 0. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore lagi memeriksa dan ketika melihat sumber daya yang tersedia itu mengurangi jumlah lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore memeriksa lagi dan ketika melihat sumber daya tersedia itu mengurangi hitungan lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore memeriksa lagi dan ketika melihat sumber daya tersedia itu mengurangi hitungan lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore.
Perbedaan utama antara semaphore biner dan mutex adalah bahwa semaphore adalah mekanisme pensinyalan dan mutex adalah mekanisme penguncian, tetapi semaphore biner tampaknya berfungsi seperti mutex yang menciptakan kebingungan, tetapi keduanya adalah konsep yang berbeda yang cocok untuk berbagai jenis pekerjaan.
Jawaban:
Mereka BUKAN hal yang sama. Mereka digunakan untuk berbagai tujuan!
Sementara kedua jenis semaphore memiliki keadaan penuh / kosong dan menggunakan API yang sama, penggunaannya sangat berbeda.
Semaphores Pengecualian Mutual Semaphores Pengecualian
Mutual digunakan untuk melindungi sumber daya bersama (struktur data, file, dll.).
Semafor Mutex "dimiliki" oleh tugas yang mengambilnya. Jika Tugas B mencoba untuk memberikan mutasi mutex yang saat ini dipegang oleh Tugas A, panggilan Tugas B akan mengembalikan kesalahan dan gagal.
Mutex selalu menggunakan urutan berikut:
Ini adalah contoh sederhana:
Binary Semaphore
Binary Semaphore menjawab pertanyaan yang sangat berbeda:
Perhatikan bahwa dengan semaphore biner, tidak apa-apa bagi B untuk mengambil semaphore dan A untuk memberikannya.
Sekali lagi, semaphore biner TIDAK melindungi sumber daya dari akses. Tindakan Memberi dan Mengambil semafor secara fundamental dipisahkan.
Biasanya tidak masuk akal untuk tugas yang sama untuk memberi dan menerima semaphore biner yang sama.
sumber
jadi semaphore lebih cocok untuk beberapa masalah sinkronisasi seperti produsen-konsumen.
Pada Windows, semaphore biner lebih seperti objek acara daripada mutex.
sumber
Mutex can be released only by thread that had acquired it
- Saya baru saja mencoba dengan program sederhana berbasis pthread_mutex, utas dapat membuka kunci mutex yang dikunci di utas utamaContoh Toilet adalah analogi yang menyenangkan:
sumber
Artikel bagus tentang topik ini:
Dari bagian 2:
sumber
Karena tidak ada jawaban di atas yang menghilangkan kebingungan, berikut adalah salah satu yang membersihkan kebingungan saya.
Sumber: http://www.geeksforgeeks.org/mutex-vs-semaphore/
sumber
Semantik sinkronisasi mereka sangat berbeda:
Dengan demikian orang dapat melihat mutex sebagai token yang diteruskan dari satu tugas ke tugas lain dan semafor sebagai lampu merah lalu lintas (ini memberi sinyal seseorang bahwa ia dapat melanjutkan).
sumber
Pada tingkat teoretis, mereka tidak berbeda secara semantik. Anda dapat menerapkan mutex menggunakan semaphores atau sebaliknya (lihat di sini untuk contoh). Dalam praktiknya, implementasinya berbeda dan mereka menawarkan layanan yang sedikit berbeda.
Perbedaan praktis (dalam hal layanan sistem di sekitarnya) adalah bahwa penerapan mutex ditujukan untuk menjadi mekanisme sinkronisasi yang lebih ringan. Dalam bahasa oracle, mutex dikenal sebagai kait dan semaphore dikenal sebagai menunggu .
Pada level terendah, mereka menggunakan semacam uji atom dan mekanisme pengaturan . Ini membaca nilai saat ini dari lokasi memori, menghitung semacam persyaratan dan menulis nilai di lokasi itu dalam satu instruksi yang tidak dapat diinterupsi . Ini berarti Anda dapat memperoleh mutex dan menguji untuk melihat apakah ada orang lain yang memilikinya sebelum Anda.
Implementasi mutex yang khas memiliki proses atau utas yang melaksanakan instruksi tes dan set dan mengevaluasi apakah ada hal lain yang telah mengatur mutex. Poin kunci di sini adalah bahwa tidak ada interaksi dengan penjadwal , jadi kami tidak tahu (dan tidak peduli) siapa yang telah mengatur kunci. Kemudian kita menyerah irisan waktu kita dan mencobanya lagi ketika tugas dijadwalkan ulang atau menjalankan spin-lock . Spin lock adalah algoritme seperti:
Ketika kami telah selesai menjalankan kode kami yang dilindungi (dikenal sebagai bagian kritis ) kami hanya menetapkan nilai mutex ke nol atau apa pun artinya 'jelas.' Jika beberapa tugas berusaha untuk mendapatkan mutex, tugas berikutnya yang dijadwalkan setelah mutex dilepaskan akan mendapatkan akses ke sumber daya. Biasanya Anda akan menggunakan mutex untuk mengontrol sumber daya yang disinkronkan di mana akses eksklusif hanya diperlukan untuk waktu yang sangat singkat, biasanya untuk membuat pembaruan ke struktur data bersama.
Semaphore adalah struktur data yang disinkronkan (biasanya menggunakan mutex) yang memiliki hitungan dan beberapa pembungkus panggilan sistem yang berinteraksi dengan scheduler sedikit lebih dalam daripada perpustakaan mutex. Semafor bertambah dan dikurangi dan digunakan untuk memblokir tugas sampai hal lain siap. Lihat Masalah Produsen / Konsumen untuk contoh sederhana ini. Semaphore diinisialisasi ke beberapa nilai - semaphore biner hanyalah kasus khusus di mana semaphore diinisialisasi ke 1. Posting ke semaphore memiliki efek membangunkan proses menunggu.
Algoritma semaphore dasar terlihat seperti:
Dalam kasus semaphore biner, perbedaan praktis utama antara keduanya adalah sifat layanan sistem yang mengelilingi struktur data aktual.
EDIT: Seperti yang ditunjukkan oleh evan dengan benar, spinlocks akan memperlambat mesin prosesor tunggal. Anda hanya akan menggunakan spinlock pada kotak multi-prosesor karena pada satu prosesor proses memegang mutex tidak akan mengatur ulang saat tugas lain sedang berjalan. Spinlocks hanya berguna pada arsitektur multi-prosesor.
sumber
futex
panggilan sistem Linux ada untuk membantu implementasi mutex / semaphore userspace latensi rendah. en.wikipedia.org/wiki/Futex ) Di jalur cepat tanpa pertengkaran, atau jika sumber daya tersedia segera, Anda tidak akan pernah memiliki overhead dari panggilan sistem. Tetapi Anda tidak menghabiskan lebih dari beberapa mikro-sibuk-menunggu (berputar). Menyetel parameter putaran balik dan tunggu adalah tergantung pada perangkat keras dan beban kerja, tetapi pustaka standar biasanya memiliki pilihan yang masuk akal.Meskipun mutex & semaphore digunakan sebagai primitif sinkronisasi, ada perbedaan besar di antara mereka. Dalam hal mutex, hanya utas yang mengunci atau mendapatkan mutex yang dapat membukanya. Dalam kasus semaphore, utas yang menunggu semafor dapat ditandai oleh utas yang berbeda. Beberapa sistem operasi mendukung penggunaan mutex & semaphores antar proses. Biasanya penggunaan dibuat di memori bersama.
sumber
Mutex: Misalkan kita memiliki utas bagian kritis T1 ingin mengaksesnya lalu mengikuti langkah-langkah di bawah ini. T1:
Binary semaphore: Ini bekerja berdasarkan signalling wait dan signal. tunggu, turunkan nilai "s" satu per satu biasanya nilai "s" diinisialisasi dengan nilai "1", sinyal meningkatkan nilai "s" satu per satu. jika nilai "s" adalah 1 berarti tidak ada yang menggunakan bagian kritis, ketika nilai 0 berarti bagian kritis digunakan. misalkan utas T2 menggunakan bagian kritis lalu mengikuti langkah-langkah di bawah ini. T2:
Perbedaan utama antara Mutex dan Binary semaphore adalah Mutext jika thread mengunci bagian kritis maka harus membuka bagian kritis tidak ada thread lain yang bisa membukanya, tetapi dalam kasus Binary semaphore jika salah satu thread mengunci bagian kritis menggunakan fungsi menunggu maka nilai dari s menjadi "0" dan tidak ada yang dapat mengaksesnya sampai nilai "s" menjadi 1 tetapi anggaplah beberapa sinyal panggilan lain maka nilai "s" menjadi 1 dan memungkinkan fungsi lain untuk menggunakan bagian kritis. karenanya dalam semaphore Biner thread tidak memiliki kepemilikan.
sumber
Pada Windows, ada dua perbedaan antara mutex dan semaphore biner:
Mutex hanya dapat dirilis oleh utas yang memiliki kepemilikan, yaitu utas yang sebelumnya disebut fungsi Tunggu, (atau yang mengambil kepemilikan saat membuatnya). Semaphore dapat dirilis oleh utas apa pun.
Utas dapat memanggil fungsi tunggu berulang kali pada mutex tanpa memblokir. Namun, jika Anda memanggil fungsi tunggu dua kali pada semaphore biner tanpa melepaskan semaphore di antaranya, utas akan memblokir.
sumber
Anda jelas menggunakan mutex untuk mengunci data dalam satu utas yang diakses oleh utas lain pada saat yang sama. Asumsikan bahwa Anda baru saja menelepon
lock()
dan sedang dalam proses mengakses data. Ini berarti bahwa Anda tidak mengharapkan utas lainnya (atau contoh lain dari kode-utas yang sama) untuk mengakses data yang sama dikunci oleh mutex yang sama. Yaitu, jika itu adalah kode-thread yang sama dijalankan pada instance thread yang berbeda, tekan kunci, makalock()
harus memblokir aliran kontrol di sana. Ini berlaku untuk utas yang menggunakan utas-kode berbeda, yang juga mengakses data yang sama dan yang juga dikunci oleh mutex yang sama. Dalam hal ini, Anda masih dalam proses mengakses data dan Anda dapat mengambil, katakanlah, 15 detik untuk mencapai pembukaan kunci mutex (sehingga utas lain yang diblokir di kunci mutex akan membuka blokir dan akan memungkinkan kontrol untuk akses data). Apakah Anda dengan biaya berapa pun membiarkan utas lain membuka kunci mutex yang sama, dan pada gilirannya, mengizinkan utas yang sudah menunggu (memblokir) dalam kunci mutex untuk membuka blokir dan mengakses data? Semoga Anda mengerti apa yang saya katakan di sini? Sesuai, disepakati definisi universal !,Jadi, jika Anda sangat khusus menggunakan binary-semaphore daripada mutex, maka Anda harus sangat berhati-hati dalam “pelingkupan” kunci dan pembatalannya. Maksud saya, setiap aliran kontrol yang mengenai setiap kunci harus mengenai panggilan pembuka, juga tidak boleh ada "pembukaan pertama", melainkan harus selalu "kunci pertama".
sumber
Mutex digunakan untuk "Mekanisme Penguncian". satu proses pada satu waktu dapat menggunakan sumber daya bersama
sedangkan
Semafor digunakan untuk "Mekanisme Pensinyalan" seperti "Saya selesai, sekarang dapat melanjutkan"
sumber
Mitos:
Beberapa artikel mengatakan bahwa "semaphore biner dan mutex sama" atau "Semaphore dengan nilai 1 adalah mutex" tetapi perbedaan dasarnya adalah Mutex hanya dapat dilepaskan oleh utas yang telah mengakuisisi, sementara Anda dapat memberi sinyal semafor dari utas lain
Poin-Poin Utama:
• Sebuah utas dapat memperoleh lebih dari satu kunci (Mutex).
• Sebuah mutex dapat dikunci lebih dari sekali hanya jika itu adalah mutex rekursif, di sini mengunci dan membuka kunci untuk mutex harus sama
• Jika utas yang sudah mengunci mutex, mencoba untuk mengunci mutex lagi, itu akan masuk ke dalam daftar tunggu mutex itu, yang mengakibatkan kebuntuan.
• Semaphore biner dan mutex serupa tetapi tidak sama.
• Mutex adalah operasi yang mahal karena protokol perlindungan yang terkait dengannya.
• Tujuan utama mutex adalah mencapai akses atom atau mengunci sumber daya
sumber
Sebuah mutex mengontrol akses ke sumber daya bersama tunggal. Ini memberikan operasi untuk memperoleh () akses ke sumber daya itu dan melepaskan () ketika selesai.
Sebuah Semaphore mengontrol akses ke kolam renang bersama sumber daya. Ini menyediakan operasi untuk Tunggu () sampai salah satu sumber daya di kumpulan tersedia, dan Sinyal () ketika diberikan kembali ke kumpulan.
Ketika jumlah sumber daya yang dilindungi Semaphore lebih besar dari 1, itu disebut Counting Semaphore . Ketika mengontrol satu sumber daya, itu disebut Boolean Semaphore . Semaphore boolean setara dengan mutex.
Jadi Semaphore adalah abstraksi level yang lebih tinggi daripada Mutex. Mutex dapat diimplementasikan menggunakan Semaphore tetapi tidak sebaliknya.
sumber
Pertanyaan yang dimodifikasi adalah - Apa perbedaan antara A mutex dan "binary" semaphore di "Linux"?
Jawab: Berikut adalah perbedaannya - i) Lingkup - Ruang lingkup mutex berada dalam ruang alamat proses yang telah membuatnya dan digunakan untuk sinkronisasi utas. Sedangkan semaphore dapat digunakan melintasi ruang proses dan karenanya dapat digunakan untuk sinkronisasi antarproses.
ii) Mutex lebih ringan dan lebih cepat dari semaphore. Futex bahkan lebih cepat.
iii) Mutex dapat diperoleh dengan utas yang sama berhasil beberapa kali dengan syarat harus melepaskannya beberapa kali. Utas lain yang mencoba mengakuisisi akan diblokir. Sedangkan dalam kasus semaphore jika proses yang sama mencoba untuk mendapatkannya kembali itu blok karena hanya dapat diperoleh satu kali.
sumber
Perbedaan antara Binary Semaphore dan Mutex: KEPEMILIKAN: Semaphores dapat diisyaratkan (diposting) bahkan dari pemilik yang tidak aktif. Ini berarti Anda cukup memposting dari utas lain, meskipun Anda bukan pemiliknya.
Semaphore adalah properti publik dalam proses, Ini dapat dengan mudah diposting oleh utas bukan pemilik. Harap Tandai perbedaan ini dalam huruf BOLD, ini sangat berarti.
sumber
Mutex bekerja pada pemblokiran wilayah kritis, Tapi Semaphore bekerja pada hitungan.
sumber
http://www.geeksforgeeks.org/archives/9102 membahas secara rinci.
Mutex
adalah mekanisme penguncian yang digunakan untuk menyinkronkan akses ke sumber daya.Semaphore
adalah mekanisme pensinyalan.Terserah programmer jika dia ingin menggunakan binary semaphore sebagai ganti mutex.
sumber
Terlepas dari kenyataan bahwa mutex memiliki pemilik, kedua objek dapat dioptimalkan untuk penggunaan yang berbeda. Mutex dirancang untuk diadakan hanya untuk waktu yang singkat; melanggar ini dapat menyebabkan kinerja yang buruk dan penjadwalan yang tidak adil. Misalnya, utas berjalan mungkin diizinkan untuk mendapatkan mutex, meskipun utas lain sudah diblokir di situ. Semafor dapat memberikan lebih banyak keadilan, atau keadilan dapat dipaksa menggunakan beberapa variabel kondisi.
sumber
sem_post()
untukSCHED_FIFO
danSCHED_RR
(kedua ini tidak default): prioritas thread tertinggi, dan jika ada beberapa dengan prioritas yang sama, benang yang telah menunggu terpanjang. OpenSolaris mengikuti aturan FIFO ini sampai taraf tertentu bahkan untuk penjadwalan normal. Untuk glibc dan FreeBSD, membuka kunci mutex sederhana (yaitu bukan prioritas memproteksi atau mewarisi prioritas) dan memposting semafor pada dasarnya sama, menandai objek sebagai tidak terkunci dan kemudian, jika mungkin ada utas menunggu, memanggil kernel untuk membangunkannya.Di windows perbedaannya adalah seperti di bawah ini. MUTEX: proses yang berhasil dijalankan menunggu harus mengeksekusi sinyal dan sebaliknya. SEMINFOR BINARY: Berbagai proses dapat menjalankan operasi menunggu atau memberi sinyal pada semaphore.
sumber
Sementara semaphore biner dapat digunakan sebagai mutex, mutex adalah use-case yang lebih spesifik, dalam hal itu hanya proses yang mengunci mutex yang seharusnya membuka kuncinya. Batasan kepemilikan ini memungkinkan untuk memberikan perlindungan terhadap:
Kendala ini tidak selalu ada karena mereka menurunkan kecepatan. Selama pengembangan kode Anda, Anda dapat mengaktifkan pemeriksaan ini sementara.
mis. Anda dapat mengaktifkan atribut Pemeriksaan kesalahan di mutex Anda. Kesalahan memeriksa mutexes kembali
EDEADLK
jika Anda mencoba untuk mengunci yang sama dua kali danEPERM
jika Anda membuka kunci mutex yang bukan milik Anda.Setelah diinisialisasi, kami dapat menempatkan cek ini dalam kode kami seperti ini:
sumber
Konsepnya jelas bagi saya setelah membahas posting di atas. Tapi ada beberapa pertanyaan yang tersisa. Jadi, saya menulis kode kecil ini.
Ketika kami mencoba memberikan semafor tanpa mengambilnya, ia berhasil melewatinya. Tetapi, ketika Anda mencoba memberikan mutex tanpa mengambilnya, itu gagal. Saya menguji ini pada platform Windows. Aktifkan USE_MUTEX untuk menjalankan kode yang sama menggunakan MUTEX.
Fakta bahwa semaphore memungkinkan Anda memberi sinyal "itu dilakukan dengan menggunakan sumber daya", meskipun tidak pernah memiliki sumber daya, membuat saya berpikir ada hubungan yang sangat longgar antara memiliki dan memberi sinyal dalam kasus semafor.
sumber
Mutex digunakan untuk melindungi kode sensitif dan data, semaphore digunakan untuk sinkronisasi. Anda juga dapat memiliki penggunaan praktis dengan melindungi kode sensitif, tetapi mungkin ada risiko yang melepaskan perlindungan oleh utas lainnya dengan operasi V.Jadi, yang utama perbedaan antara bi-semaphore dan mutex adalah kepemilikan. Misalnya dengan toilet, Mutex seperti itu orang bisa masuk toilet dan mengunci pintu, tidak ada orang lain yang bisa masuk sampai pria itu keluar, bi-semaphore seperti itu yang bisa masuk toilet dan mengunci pintu, tetapi orang lain bisa masuk dengan meminta administrator untuk membuka pintu, itu konyol.
sumber
Mutex
Mutex biasanya digunakan untuk membuat serialisasi akses ke bagian kode re-entrant yang tidak dapat dieksekusi secara bersamaan oleh lebih dari satu utas. Objek mutex hanya memungkinkan satu utas masuk ke bagian yang dikontrol, memaksa utas lain yang berupaya mendapatkan akses ke bagian itu untuk menunggu sampai utas pertama keluar dari bagian itu. Penggunaan yang benar dari mutex adalah untuk melindungi sumber daya bersama yang dapat memiliki bahaya. efek samping yang tidak diinginkan. Dua tugas RTOS yang beroperasi pada prioritas yang berbeda dan berkoordinasi melalui mutex, menciptakan peluang untuk inversi prioritas . Mutex bekerja di ruang pengguna .
Tiang sinyal
Semaphore adalah mekanisme pensinyalan. Semaphore membatasi jumlah pengguna simultan dari sumber daya bersama hingga jumlah maksimum. Thread dapat meminta akses ke sumber daya (menurunkan semaphore) dan dapat memberi sinyal bahwa mereka telah selesai menggunakan sumber daya (incrementing the semaphore). Ini memungkinkan sejumlah utas untuk mengakses sumber daya bersama. Penggunaan semafor yang benar adalah untuk pensinyalan dari satu tugas ke tugas lainnya. Memori juga dapat digunakan untuk memberi sinyal dari interrupt service routine (ISR) ke suatu tugas. Signaling semaphore adalah perilaku RTOS yang tidak menghalangi dan dengan demikian ISR aman. Karena teknik ini menghilangkan kebutuhan yang rawan kesalahan untuk menonaktifkan interupsi pada tingkat tugas. Ini bekerja di ruang kernel .
sumber
Jawabannya mungkin tergantung pada OS target. Sebagai contoh, setidaknya satu implementasi RTOS yang saya kenal akan memungkinkan beberapa operasi "get" berurutan terhadap satu OS mutex, asalkan semuanya dari dalam konteks utas yang sama. Beberapa get harus diganti dengan jumlah put yang sama sebelum thread lain diizinkan untuk mendapatkan mutex. Ini berbeda dari semaphore biner, yang hanya dapat satu kali diizinkan pada satu waktu, terlepas dari konteks utas.
Gagasan di balik jenis mutex ini adalah bahwa Anda melindungi objek dengan hanya mengizinkan satu konteks untuk memodifikasi data pada suatu waktu. Bahkan jika utas mendapatkan mutex dan kemudian memanggil fungsi yang lebih lanjut memodifikasi objek (dan mendapat / menempatkan pelindung mutex di sekitar operasinya sendiri), operasi harus tetap aman karena semuanya terjadi di bawah utas tunggal.
Tentu saja, ketika menggunakan fitur ini, Anda harus yakin bahwa semua akses dalam satu utas benar-benar aman!
Saya tidak yakin seberapa umum pendekatan ini, atau apakah itu berlaku di luar sistem yang saya kenal. Untuk contoh mutex semacam ini, lihat ThreadX RTOS.
sumber
Mutex memiliki kepemilikan, tidak seperti semaphore. Meskipun setiap utas, dalam lingkup mutex, bisa mendapatkan mutex yang tidak dikunci dan mengunci akses ke bagian kode yang sama, hanya utas yang mengunci mutex yang akan membukanya .
sumber
Seperti yang telah disebutkan oleh banyak orang di sini, sebuah mutex digunakan untuk melindungi bagian penting dari kode (bagian kritis AKA.) Anda akan memperoleh mutex (kunci), memasuki bagian kritis, dan melepaskan mutex (membuka) semua di utas yang sama .
Saat menggunakan semaphore, Anda dapat membuat utas menunggu di semafor (katakan utas A), hingga utas lainnya (misalkan utas B) menyelesaikan tugas apa pun, lalu setel Semafor untuk utas A untuk menghentikan penantian, dan melanjutkan tugasnya.
sumber
Solusi terbaik
Satu-satunya perbedaan adalah
1.Mutex -> mengunci dan membuka kunci berada di bawah kepemilikan utas yang mengunci mutex.
2.Semaphore -> Tanpa kepemilikan yaitu; jika satu utas panggilan sedang menunggu utas lainnya dapat memanggil sempost untuk menghapus kunci.
sumber
MUTEX
Sampai saat ini, satu-satunya kunci tidur di kernel adalah semaphore. Sebagian besar pengguna semaphore membuat semaphore dengan hitungan satu dan memperlakukan mereka sebagai kunci pengecualian bersama - versi tidur dari kunci-kunci. Sayangnya, semaphore agak generik dan tidak memaksakan batasan penggunaan. Ini membuatnya berguna untuk mengelola akses eksklusif dalam situasi yang tidak jelas, seperti tarian rumit antara kernel dan ruang pengguna. Tetapi itu juga berarti bahwa penguncian yang lebih sederhana lebih sulit untuk dilakukan, dan kurangnya aturan yang ditegakkan membuat segala jenis debugging otomatis atau penegakan kendala menjadi tidak mungkin. Mencari kunci tidur yang lebih sederhana, pengembang kernel memperkenalkan mutex. Ya, seperti yang biasa Anda lakukan, itu adalah nama yang membingungkan. Mari kita perjelas. Istilah “mutex” adalah nama generik untuk merujuk pada kunci tidur apa pun yang memberlakukan saling pengecualian, seperti semaphore dengan hitungan penggunaan satu. Dalam kernel Linux baru-baru ini, kata benda yang tepat "mutex" sekarang juga merupakan jenis kunci penguncian khusus yang menerapkan saling pengecualian. Artinya, mutex adalah mutex.
Kesederhanaan dan efisiensi dari mutex berasal dari kendala tambahan yang dikenakan pada penggunanya melebihi dan melebihi apa yang semafor butuhkan. Tidak seperti semaphore, yang menerapkan perilaku paling dasar sesuai dengan desain asli Dijkstra, mutex memiliki kasus penggunaan yang lebih ketat, lebih sempit: n Hanya satu tugas yang dapat menahan mutex pada suatu waktu. Artinya, jumlah penggunaan pada mutex selalu satu.
[1] Pengembangan Kernel Linux, Edisi Ketiga Robert Love
sumber
Saya pikir sebagian besar jawaban di sini membingungkan terutama yang mengatakan bahwa mutex dapat dirilis hanya oleh proses yang menahannya tetapi semaphore dapat ditandai oleh proses. Baris di atas agak kabur dalam hal semafor. Untuk memahami kita harus tahu bahwa ada dua jenis semaphore satu disebut berhitung semaphore dan yang lainnya disebut binary semaphore. Dalam penghitungan semaphore menangani akses ke n jumlah sumber daya di mana n dapat didefinisikan sebelum penggunaan. Setiap semaphore memiliki variabel jumlah, yang menjaga jumlah jumlah sumber daya yang digunakan, awalnya, diatur ke n. Setiap proses yang ingin menggunakan sumber daya melakukan operasi menunggu () pada semaphore (dengan demikian mengurangi jumlah). Ketika suatu proses melepaskan sumber daya, ia melakukan operasi rilis () (menambah jumlah). Saat hitungan menjadi 0, semua sumber daya digunakan. Setelah itu, proses menunggu hingga hitungan menjadi lebih dari 0. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore lagi memeriksa dan ketika melihat sumber daya yang tersedia itu mengurangi jumlah lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore memeriksa lagi dan ketika melihat sumber daya tersedia itu mengurangi hitungan lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore. Sekarang di sini adalah tangkapan hanya proses yang memegang sumber daya dapat meningkatkan jumlah tidak ada proses lain dapat meningkatkan jumlah hanya proses memegang sumber daya dapat meningkatkan jumlah dan proses menunggu semaphore memeriksa lagi dan ketika melihat sumber daya tersedia itu mengurangi hitungan lagi. Jadi dalam hal binary semaphore, hanya proses memegang semaphore yang dapat meningkatkan jumlah, dan penghitungan tetap nol sampai berhenti menggunakan semaphore dan meningkatkan jumlah dan proses lainnya mendapat kesempatan untuk mengakses semaphore.
Perbedaan utama antara semaphore biner dan mutex adalah bahwa semaphore adalah mekanisme pensinyalan dan mutex adalah mekanisme penguncian, tetapi semaphore biner tampaknya berfungsi seperti mutex yang menciptakan kebingungan, tetapi keduanya adalah konsep yang berbeda yang cocok untuk berbagai jenis pekerjaan.
sumber