Dua sen saya di Mutex dan Semaphore di C #

Sinkronisasi utas digunakan untuk mencegah beberapa utas mengakses sumber daya bersama secara bersamaan. Mutex dan Semaphore adalah dua konsep terkait yang paling penting. Mari kita pahami apa keduanya dan kapan kita harus menggunakannya.

Sebelum kita memulai diskusi kita, mari kita lihat sekilas konsep dasar. Utas adalah unit eksekusi terkecil dalam suatu proses. Pada dasarnya, multi-threading membantu Anda melakukan beberapa tugas secara bersamaan dan karenanya meningkatkan throughput aplikasi secara keseluruhan.

Mutex adalah primitif sinkronisasi yang dapat bekerja lintas proses - yaitu, dapat digunakan untuk sinkronisasi antar proses. Sebaliknya, Semaphore adalah salah satu yang memungkinkan Anda membatasi jumlah utas yang memiliki akses ke sumber daya bersama pada titik waktu yang sama. Intinya, Semaphore adalah bentuk Mutex yang lebih umum.

Semaphore digunakan untuk membatasi jumlah utas yang dapat memiliki akses ke sumber daya bersama secara bersamaan. Intinya, ini digunakan untuk membatasi jumlah konsumen untuk sumber daya bersama tertentu secara bersamaan. Anda dapat memanfaatkan Semaphore untuk menerapkan penguncian non-eksklusif dan karenanya membatasi konkurensi.

Perhatikan bahwa Mutex digunakan untuk penguncian eksklusif pada sumber daya bersama. Dengan kata lain, Mutex memungkinkan Anda memperoleh kunci yang saling eksklusif - utas mana pun akan memiliki akses ke sumber daya bersama pada titik waktu tertentu. Penguncian eksklusif digunakan untuk memastikan bahwa pada titik waktu tertentu, satu dan hanya satu utas yang dapat memasuki bagian kritis. Bagian penting dapat didefinisikan sebagai struktur data atau sumber daya yang digunakan bersama oleh beberapa utas, tetapi satu dan hanya satu utas yang dapat memiliki akses ke sana pada titik waktu tertentu.

Kelas System.Threading.Mutex mewakili Mutex dan kelas System.Threading.Semaphore digunakan untuk bekerja dengan Semaphores. Anda dapat menggunakan metode WaitOne pada sebuah instance kelas Mutex untuk mengunci dan menggunakan metode ReleaseMutex untuk membuka kunci.

Mutex mutexObject = new Mutex(false, "Demo");

if (!mutexObject.WaitOne(TimeSpan.FromSeconds(10), false))

     {

             Console.WriteLine("Quitting for now as another instance is in execution...");

               return;

     }

Untuk membuat Semaphore di C #, Anda harus membuat instance dari kelas Semaphore. Saat membuat instance Semaphore, Anda perlu meneruskan dua argumen ke konstruktor argumennya. Sementara argumen pertama digunakan untuk menunjukkan jumlah entri sumber daya awal, argumen kedua digunakan untuk menentukan jumlah maksimum entri sumber daya bersamaan. Perhatikan bahwa jika Anda ingin mencadangkan semua slot untuk utas baru yang akan dibuat, Anda harus menentukan nilai yang identik untuk kedua parameter ini. Potongan kode berikut menggambarkan bagaimana Anda dapat membuat semaphore di C #.

public static Semaphore threadPool = new Semaphore(3, 5);

Lihat potongan kode yang diberikan di atas. Pernyataan di atas membuat objek semaphore bernama threadPool yang dapat mendukung maksimal 5 permintaan bersamaan. Perhatikan bahwa hitungan awal disetel ke 3 seperti yang ditunjukkan pada parameter pertama ke konstruktor. Ini menyiratkan bahwa 2 slot disediakan untuk utas saat ini dan 3 slot tersedia untuk utas lainnya. Sekarang mari kita menulis beberapa kode!

Cuplikan kode berikut menunjukkan bagaimana Anda dapat membuat dan memulai 10 utas menggunakan kelas Thread yang tersedia di namespace System.Threading. Perhatikan bagaimana delegasi ThreadStart telah digunakan.

for (int i = 0; i < 10; i++)

{

   Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

   threadObject.Name = "Thread Name: " + i;

   threadObject.Start();

}

Berikut kode metode PerformSomeWork. Ini adalah metode yang sebenarnya berisi kode untuk bekerja dengan semaphore.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

Lihat metode PerformSomeWork yang diberikan di atas. Metode WaitOne dipanggil pada instance Semaphore untuk memblokir utas saat ini hingga sinyal diterima. Metode Rilis dipanggil pada instance yang sama untuk merilis semaphore. Berikut daftar kode lengkap untuk referensi Anda.

class SemaphoreDemo

   {

       public static Semaphore threadPool = new Semaphore(3, 5);

       public static void Main(string[] args)

       {

           for (int i = 0; i < 10; i++)

           {

               Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

               threadObject.Name = "Thread Name: " + i;

               threadObject.Start();

           }

           Console.ReadLine();

       }

       private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

   }