Moja dva centa za Mutex i Semafor u C #

Sinkronizacija niti koristi se kako bi se spriječilo da više niti istovremeno pristupa zajedničkom resursu. Mutex i Semaphore dva su najvažnija srodna koncepta. Razumijemo što su i jedno i drugo i kada bismo ih trebali koristiti.

Prije nego započnemo našu raspravu, pogledajmo na brzinu osnovne pojmove. Nit je najmanja izvršna jedinica u procesu. U osnovi, višenitnost vam pomaže da istovremeno izvršavate nekoliko zadataka i time povećavate ukupnu propusnost aplikacije.

Mutex je primitiv za sinkronizaciju koji može raditi u različitim procesima - tj. Može se koristiti za međusobnu sinkronizaciju. Semafor je, naprotiv, onaj koji vam omogućuje da ograničite broj niti koje imaju pristup zajedničkom resursu u isto vrijeme. U osnovi je Semafor općenitiji oblik Mutexa.

Semafor se koristi za ograničavanje broja niti koje istovremeno mogu imati pristup zajedničkom resursu. U osnovi se koristi za istovremeno ograničavanje broja potrošača određenog zajedničkog resursa. Možete iskoristiti prednost Semaphorea za implementaciju neekskluzivnog zaključavanja i time ograničiti istodobnost.

Imajte na umu da se Mutex koristi za ekskluzivno zaključavanje zajedničkog resursa. Drugim riječima, Mutex vam omogućuje stjecanje međusobno isključivog zaključavanja - bilo koja nit imala bi pristup zajedničkom resursu u određenom trenutku. Ekskluzivno zaključavanje koristi se kako bi se osiguralo da u bilo kojem trenutku, jedna i samo jedna nit može ući u kritični odjeljak. Kritični odjeljak može se definirati kao struktura podataka ili resurs koji dijeli više niti, ali jedna i samo jedna nit može mu pristupiti u bilo kojem trenutku.

Klasa System.Threading.Mutex predstavlja Mutex, a klasa System.Threading.Semaphore koristi se za rad sa Semaforima. Možete koristiti metodu WaitOne na instanci klase Mutex za zaključavanje i otključavanje pomoću metode ReleaseMutex.

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;

     }

Da biste stvorili Semaphore u C #, trebali biste stvoriti instancu klase Semaphore. Kada kreirate instancu Semaphore, morate proslijediti dva argumenta njegovom konstruktoru argumenata. Dok se prvi argument koristi za označavanje broja početnih unosa resursa, drugi se argument koristi za određivanje maksimalnog broja istodobnih unosa resursa. Imajte na umu da ako želite rezervirati sva mjesta za nove niti koje će se stvoriti, trebali biste navesti identične vrijednosti za oba ova parametra. Sljedeći isječak koda ilustrira kako možete stvoriti semafor u C #.

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

Pogledajte gore navedeni isječak koda. Gornja izjava stvara objekt semafora nazvan threadPool koji može podržati najviše 5 istodobnih zahtjeva. Imajte na umu da je početni broj postavljen na 3 kao što je naznačeno u prvom parametru konstruktora. To podrazumijeva da su 2 utora rezervirana za trenutnu nit, a 3 utora dostupna su za ostale niti. Napišimo sada neki kod!

Sljedeći isječak koda pokazuje kako možete stvoriti i pokrenuti 10 niti pomoću klase Thread koja je dostupna u imenskom prostoru System.Threading. Obratite pažnju na to kako je korišten delegat ThreadStart.

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

{

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

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

   threadObject.Start();

}

Evo koda metode PerformSomeWork. Ovo je metoda koja zapravo sadrži kod za rad sa semaforima.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

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

           Thread.Sleep(10000);

           threadPool.Release();

       }

Pogledajte gore navedenu metodu PerformSomeWork. Metoda WaitOne poziva se na instancu Semaphore da blokira trenutnu nit dok se ne primi signal. Metoda otpuštanja poziva se na istoj instanci za oslobađanje semafora. Evo kompletnog popisa kodova za vašu referencu.

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();

       }

   }