Bagaimana cara memilih antara Semaphore dan SemaphoreSlim?

109

Antarmuka publik mereka tampak serupa. The dokumentasi menyatakan bahwa SemaphoreSlim adalah alternatif ringan dan tidak menggunakan Semaphore Kernel Windows. Sumber daya ini menyatakan bahwa SemaphoreSlim jauh lebih cepat. Dalam situasi apa SemaphoreSlim lebih masuk akal daripada Semaphore dan sebaliknya?

Michael Hedgpeth
sumber
1
Semaphore selalu meneruskan pekerjaan ke OS. Itu membuatnya relatif mahal jika semaphore tidak diganggu gugat, panggilan kernel dengan mudah membutuhkan biaya 400 nanodetik. Bantuan ramping pertama kali mencoba melakukannya dengan murah dengan variabel bersama, hanya memanggil ke OS ketika itu tidak berhasil. Anda selalu suka murah, kecuali dalam kasus sudut di mana semaphore perlu dibagikan oleh banyak proses.
Hans Passant

Jawaban:

64

Satu perbedaan adalah bahwa SemaphoreSlimtidak mengizinkan semaphores bernama, yang dapat mencakup seluruh sistem. Ini berarti SemaphoreSlim tidak dapat digunakan untuk sinkronisasi lintas proses.

Dokumentasi MSDN juga menunjukkan bahwa SemSlim harus digunakan ketika "waktu tunggu diharapkan sangat singkat". Itu biasanya cocok dengan gagasan bahwa versi ramping lebih ringan untuk sebagian besar trade off.

Andrew Barber
sumber
66
Saya berharap MS telah menulis sesuatu tentang apa yang terjadi ketika waktu tunggu tidak "sangat singkat".
John Reynolds
79
... atau apa artinya "sangat singkat"
Richard Szalay
9
Tergantung pada sistemnya, 1 mikrodetik untuk Semaphore dan 1/4 mikrodetik untuk SemaphoreSlim untuk melakukan WaitOne atau Release ["C # 5.0 in a Nutshell" hal. 890] Jadi mungkin itu yang mereka maksud dengan waktu tunggu yang sangat singkat?
David Sherret
2
@dho Referensi yang bagus! Tapi saya menduga artikel terkait berarti "ketika waktu tunggu untuk mengakses sumber daya bersama sangat singkat" - yaitu sumber daya tidak akan tetap digunakan secara eksklusif untuk jangka waktu yang lama - daripada berarti waktu tunggu untuk kode semaphore itu sendiri? Kode semaphore akan selalu dijalankan terlepas dari berapa lama sumber daya tetap terkunci.
culix
4
@culix Melihat sumber Semaphore versus SemaphoreSlim Saya menduga alasan utama bahwa SemaphoreSlim hanya boleh digunakan untuk menunggu "sangat singkat" adalah karena menggunakan spin menunggu. Ini lebih responsif, tetapi memakan banyak CPU dan akan sia-sia untuk waktu tunggu yang lebih lama di mana tanggapan seketika kurang penting. Semaphore memblokir utas sebagai gantinya.
r2_118
17

Dokumentasi MSDN menjelaskan perbedaannya.

Dalam satu kalimat:

  • Kelas SemaphoreSlim mewakili semaphore ringan dan cepat yang dapat digunakan untuk menunggu dalam satu proses ketika waktu tunggu diperkirakan sangat singkat.
Joe
sumber
1
Untuk menambah ini, gunakan SemaphoreSlim dalam semua kasus di mana aplikasi Anda adalah satu-satunya proses di komputer Anda yang akan perlu mengakses Semaphore itu.
Austin Salgat
2
@Salgat Mengapa Anda melakukan itu? Seperti yang dijabarkan dalam jawaban lain, SemaphoreSlimdiimplementasikan menggunakan SpinWait, jadi jika Anda banyak menunggu, Anda akan membuang banyak waktu CPU. Yang bahkan bukan ide yang baik jika proses Anda adalah satu-satunya proses di komputer.
M. Stramm
Dari dokumentasi MSDN, "Kelas SemaphoreSlim adalah semaphore yang direkomendasikan untuk sinkronisasi dalam satu aplikasi.". Kecuali untuk kasus khusus, Anda harus default menggunakan SemaphoreSlim jika hanya satu proses yang menggunakan semaphore itu. Pengecualian khusus umumnya ada untuk semua tipe data bersamaan, yang tidak perlu dikatakan lagi.
Austin Salgat
17

SemaphoreSlim didasarkan pada SpinWait dan Monitor, jadi utas yang menunggu untuk mendapatkan kunci sedang membakar siklus CPU untuk beberapa waktu dengan harapan mendapatkan kunci sebelum menyerah ke utas lain. Jika itu tidak terjadi, maka utas memungkinkan sistem untuk beralih konteks dan mencoba lagi (dengan membakar beberapa siklus CPU) setelah OS menjadwalkan utas itu lagi. Dengan menunggu lama, pola ini dapat membakar sejumlah besar siklus CPU. Jadi skenario kasus terbaik untuk penerapan tersebut adalah ketika sebagian besar waktu tidak ada waktu tunggu dan Anda hampir dapat memperoleh kunci secara instan.

Semaphore bergantung pada implementasi di kernel OS, jadi setiap kali Anda mendapatkan kunci, Anda menghabiskan cukup banyak siklus CPU, tetapi setelah itu utas hanya tidur selama diperlukan untuk mendapatkan kunci.

Dmytro Zakharov
sumber
12

Mengenai kontroversi "waktu singkat":

Setidaknya dokumentasi SemaphoreSlim MSDN menyatakan itu

Kelas SemaphoreSlim adalah semaphore yang direkomendasikan untuk sinkronisasi dalam satu aplikasi.

di bagian Keterangan. Bagian yang sama juga menjelaskan perbedaan utama antara Semaphore dan SemaphoreSlim:

SemaphoreSlim adalah alternatif ringan untuk kelas Semaphore yang tidak menggunakan semaphore kernel Windows. Berbeda dengan kelas Semaphore, kelas SemaphoreSlim tidak mendukung semaphore sistem bernama. Anda hanya dapat menggunakannya sebagai semaphore lokal.

Shaedar
sumber
1
Lebih detail: [SemaphoreSlim and other locks] use busy spinning for brief periods before they put the thread into a true Wait state. When wait times are expected to be very short, spinning is far less computationally expensive than waiting, which involves an expensive kernel transition: dotnet.github.io/docs/essentials/collections/...
Marco Sulla
0

Saya melihat kode sumber di sini dan inilah yang saya dapatkan:

  1. Baik Semaphore dan SemaphoreSlim berasal dari WaitHandle yang secara internal menggunakan pegangan asli Win32. Itulah mengapa Anda perlu membuang () keduanya. Jadi dugaan bahwa Slim itu ringan patut dicurigai.

  2. SemaphoreSlim menggunakan SpinWait secara internal sementara Semaphore tidak. Itu memberi tahu saya bahwa dalam kasus di mana menunggu diperkirakan akan lama, Semaphore harus melakukan lebih baik setidaknya dalam arti tidak akan mencekik CPU Anda.

ILIA BROUDNO
sumber
2
SemaphoreSlim tidak diturunkan dari WaitHandle. Sebenarnya itu dibuat dengan satu tujuan - untuk menghilangkan turunan dari WaitHandle, yang merupakan primitif ruang kernel, dalam tugas-tugas di mana Anda perlu menyinkronkan operasi hanya di dalam satu proses.
Igor V Savchenko