Semaphore dan SemaphoreSlim
Kelas System.Threading.Semaphore mewakili semaphore bernama (systemwide) atau lokal. Ini adalah pembungkus tipis di sekitar objek semaphore Win32. Semaphore Win32 menghitung semaphore, yang dapat digunakan untuk mengontrol akses ke kumpulan sumber daya.
Kelas SemaphoreSlim ini mewakili semaphore ringan dan cepat yang dapat digunakan untuk menunggu dalam satu proses ketika waktu tunggu diperkirakan akan sangat singkat. SemaphoreSlim bergantung sebanyak mungkin pada sinkronisasi primitif yang disediakan oleh runtime bahasa umum (CLR). Namun, juga menyediakan gagang tunggu berbasis kernel yang diinisialisasi dengan malas seperlunya untuk mendukung penungguan beberapa semaphore. SemaphoreSlim juga mendukung penggunaan token pembatalan, tetapi tidak mendukung semaphores bernama atau penggunaan handel tunggu untuk sinkronisasi.
Mengelola Sumber Daya Terbatas
Utas memasuki semaphore dengan memanggil metode WaitOne, yang diwarisi dari kelas WaitHandle, dalam kasus objek System.Threading.Semaphore, atau metode SemaphoreSlim.Wait atau SemaphoreSlim.WaitAsync, dalam kasus objek SemaphoreSlim. Ketika panggilan kembali, hitungan pada semaphore dikurangi. Saat utas meminta entri dan hitungannya adalah nol, utas tersebut memblokir. Saat utas melepaskan semaphore dengan memanggil metode Semaphore.Release atau SemaphoreSlim.Release, utas yang diblokir diizinkan untuk masuk. Tidak ada urutan yang dijamin, seperti pertama-masuk, pertama-keluar, (FIFO) atau terakhir-masuk, pertama-keluar (LIFO), untuk utas yang diblokir dalam memasuki semaphore.
Utas dapat memasuki semaphore beberapa kali dengan memanggil metode System.Threading.Semaphore dari objekWaitOne atau metode SemaphoreSlim dari objek Wait berulang kali. Untuk melepaskan semaphore, utas dapat memanggil kelebihan beban metode Semaphore.Release() atau SemaphoreSlim.Release() dalam jumlah kali yang sama, atau memanggil kelebihan beban metode Semaphore.Release(Int32) atau SemaphoreSlim.Release(Int32) dan menentukan jumlah entri yang akan dirilis.
Semaphore dan Identitas Utas
Dua jenis semaphore tidak memberlakukan identitas utas pada panggilan ke metode WaitOne, Wait, Release, dan SemaphoreSlim.Release. Misalnya, skenario penggunaan umum untuk semaphore melibatkan utas produsen dan utas konsumen, dengan satu utas selalu meningkatkan jumlah semaphore dan yang lain selalu menguranginya.
Programmer lah yang bertanggung jawab untuk memastikan bahwa utas tidak melepaskan semaphore terlalu sering. Misalnya, bila semaphore memiliki jumlah maksimum dua, dan utas A dan utas B keduanya memasuki semaphore tersebut. Jika kesalahan pemrograman di utas B menyebabkannya memanggil Release
dua kali, maka kedua panggilan berhasil. Hitungan pada semaphore penuh, dan ketika utas A akhirnya memanggil Release
, maka SemaphoreFullException dilemparkan.
Semaphore Bernama
Sistem operasi Windows memungkinkan semaphores memiliki nama. Semaphore bernama adalah sistem lebar. Artinya, setelah aktivitas bernama dibuat, maka akan terlihat oleh semua utas di semua proses. Dengan demikian, aktivitas bernama dapat digunakan untuk menyinkronkan aktivitas proses maupun rangkaian.
Anda dapat membuat objek Semaphore yang mewakili semaphore sistem bernama dengan menggunakan salah satu konstruktor yang menentukan suatu nama.
Catatan
Karena semaphore bernama merupakan luas sistem, dimungkinkan untuk memiliki beberapa objek Semaphore yang mewakili semaphore yang bernama yang sama. Setiap kali Anda memanggil konstruktor, atau metode Semaphore.OpenExisting, objek Semaphore baru dibuat. Menentukan nama yang sama berulang kali membuat beberapa objek yang mewakili semaphore yang bernama sama.
Berhati-hatilah ketika Anda menggunakan semaphore bernama. Karena semaphore merupakan luas sistem, proses lain yang menggunakan nama yang sama dapat masuk ke semaphore Anda secara tak terduga. Kode berbahaya yang dijalankan pada komputer yang sama dapat menggunakan ini sebagai dasar penolakan serangan layanan.
Gunakan keamanan kontrol akses untuk melindungi objek Semaphore yang mewakili semaphore bernama, sebaiknya dengan menggunakan konstruktor yang menentukan objek System.Security.AccessControl.SemaphoreSecurity. Anda juga dapat menerapkan keamanan kontrol akses menggunakan metode Semaphore.SetAccessControl, tetapi ini meninggalkan jendela kerentanan antara waktu pembuatan semaphore dan waktu semaphore itu dilindungi. Melindungi semaphore dengan keamanan kontrol akses membantu mencegah serangan berbahaya, tetapi tidak menyelesaikan masalah tabrakan nama yang tidak disengaja.