Dua sen saya di Mutex dan Semaphore di C #

Penyegerakan benang digunakan untuk mengelakkan beberapa utas mengakses sumber yang dikongsi secara serentak. Mutex dan Semaphore adalah dua konsep berkaitan yang paling penting. Mari kita fahami apakah kedua-duanya dan kapan kita harus menggunakannya.

Sebelum memulakan perbincangan, mari kita lihat konsep asas dengan cepat. Benang adalah unit pelaksanaan terkecil dalam proses. Pada dasarnya, multi-threading membantu anda melakukan beberapa tugas secara serentak dan dengan itu meningkatkan keseluruhan hasil aplikasi.

Mutex adalah primitif penyegerakan yang dapat berfungsi merentasi proses - iaitu, ia boleh digunakan untuk penyegerakan proses antar. Semaphore sebaliknya adalah yang membolehkan anda mengehadkan bilangan utas yang mempunyai akses ke sumber bersama pada masa yang sama. Pada hakikatnya, Semaphore adalah bentuk Mutex yang lebih umum.

Semaphore digunakan untuk mengehadkan bilangan utas yang dapat mengakses sumber yang dikongsi bersamaan. Pada dasarnya, ia digunakan untuk membatasi jumlah pengguna untuk sumber bersama tertentu secara bersamaan. Anda boleh memanfaatkan Semaphore untuk melaksanakan penguncian bukan eksklusif dan dengan itu menghadkan serentak.

Perhatikan bahawa Mutex digunakan untuk mengunci eksklusif pada sumber yang dikongsi. Dengan kata lain, Mutex membolehkan anda memperoleh kunci yang saling eksklusif - mana-mana satu rangkaian mempunyai akses ke sumber yang dikongsi pada satu masa tertentu. Penguncian eksklusif digunakan untuk memastikan bahawa pada satu-satu masa tertentu, satu dan hanya satu utas dapat memasuki bahagian kritikal. Bahagian kritikal boleh didefinisikan sebagai struktur data atau sumber yang dikongsi oleh beberapa utas tetapi satu dan hanya satu utas dapat mengaksesnya pada suatu waktu tertentu.

Kelas System.Threading.Mutex mewakili Mutex dan sistem System.Threading.Semaphore digunakan untuk bekerja dengan Semaphores. Anda boleh menggunakan kaedah WaitOne pada contoh kelas Mutex untuk mengunci dan menggunakan kaedah 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 contoh kelas Semaphore. Semasa membuat contoh Semaphore, anda perlu menyampaikan dua argumen kepada pembina argumennya. Walaupun argumen pertama digunakan untuk menunjukkan jumlah entri sumber awal, argumen kedua digunakan untuk menentukan jumlah maksimum entri sumber serentak. Perhatikan bahawa jika anda ingin menempah semua slot untuk utas baru yang akan dibuat, anda harus menentukan nilai yang sama untuk kedua parameter ini. Coretan kod berikut menggambarkan bagaimana anda boleh membuat semaphore di C #.

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

Rujuk coretan kod yang diberikan di atas. Pernyataan di atas membuat objek semaphore bernama threadPool yang dapat menyokong maksimum 5 permintaan serentak. Perhatikan bahawa kiraan awal ditetapkan ke 3 seperti yang ditunjukkan dalam parameter pertama ke konstruktor. Ini menunjukkan bahawa 2 slot disediakan untuk utas semasa dan 3 slot tersedia untuk utas lain. Mari sekarang tulis beberapa kod!

Coretan kod berikut menunjukkan bagaimana anda boleh membuat dan memulakan 10 utas menggunakan kelas Thread yang tersedia di System.Threading namespace. Perhatikan bagaimana perwakilan ThreadStart telah digunakan.

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

{

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

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

   threadObject.Start();

}

Inilah kod kaedah PerformSomeWork. Ini adalah kaedah yang sebenarnya mengandungi kod untuk bekerja dengan semaphores.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

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

           Thread.Sleep(10000);

           threadPool.Release();

       }

Rujuk kaedah PerformSomeWork yang diberikan di atas. Kaedah WaitOne dipanggil pada contoh Semaphore untuk menyekat utas semasa sehingga isyarat diterima. Kaedah Release dipanggil pada contoh yang sama untuk melepaskan semaphore. Inilah senarai kod lengkap untuk rujukan 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();

       }

   }