Programiranje

Moja dva centa za Mutex in Semafor v C #

Sinhronizacija niti se uporablja za preprečevanje hkratnega dostopa več niti do vira v skupni rabi. Mutex in Semaphore sta dva najpomembnejša sorodna koncepta. Razumejmo, kaj je oboje in kdaj bi jih morali uporabiti.

Preden začnemo z razpravo, si na hitro oglejmo osnovne koncepte. Nit je najmanjša enota izvrševanja v procesu. V bistvu vam večnitnost pomaga hkrati izvajati več nalog in s tem povečati skupno pretočnost aplikacije.

Mutex je primitiv za sinhronizacijo, ki lahko deluje med procesi - torej se lahko uporablja za sinhronizacijo med procesi. Nasprotno, semafor je tisti, ki vam omogoča, da v istem trenutku omejite število niti, ki imajo dostop do vira v skupni rabi. V bistvu je semafor bolj splošna oblika mutexa.

Semafor se uporablja za omejevanje števila niti, ki imajo lahko hkrati dostop do vira v skupni rabi. V bistvu se hkrati uporablja za omejevanje števila potrošnikov za določen deljeni vir. Semaphore lahko izkoristite za izvajanje neizključnega zaklepanja in s tem omejitev sočasnosti.

Upoštevajte, da se Mutex uporablja za izključno zaklepanje vira v skupni rabi. Z drugimi besedami, Mutex vam omogoča pridobitev medsebojno izključujoče ključavnice - katera koli nit bi imela v določenem trenutku dostop do vira v skupni rabi. Ekskluzivno zaklepanje se uporablja za zagotovitev, da lahko v danem trenutku ena in samo ena nit vstopi v kritični odsek. Kritični odsek je lahko opredeljen kot podatkovna struktura ali vir, ki si ga deli več niti, vendar ima lahko ena in samo ena nit dostop do njega v danem trenutku.

Razred System.Threading.Mutex predstavlja Mutex, razred System.Threading.Semaphore pa se uporablja za delo s Semaphores. Za zaklepanje in uporabo metode ReleaseMutex lahko uporabite metodo WaitOne na primerku razreda Mutex.

Mutex mutexObject = nov Mutex (napačno, "Demo");

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

     {

Console.WriteLine ("Zaustavitev za zdaj, ko se izvaja drug primerek ...");

vrnitev;

     }

Če želite ustvariti Semaphore v C #, ustvarite primerek razreda Semaphore. Ko ustvarjate primerek Semaphore, morate njegovemu konstruktorju argumentov posredovati dva argumenta. Medtem ko se prvi argument uporablja za označevanje števila začetnih vnosov virov, drugi argument uporablja za določanje največjega števila sočasnih vnosov virov. Če želite rezervirati vse reže za nove niti, ki bi bile ustvarjene, morate za oba parametra določiti enake vrednosti. Naslednji delček kode prikazuje, kako lahko v C # ustvarite semafor.

javni statični Semaphore threadPool = nov Semaphore (3, 5);

Glejte zgornji delček kode. Zgornji stavek ustvari objekt semaforja z imenom threadPool, ki lahko podpira največ 5 sočasnih zahtev. Upoštevajte, da je začetno število nastavljeno na 3, kot je navedeno v prvem parametru konstruktorja. To pomeni, da sta za trenutno nit rezervirani 2 reži, za druge niti pa 3 reže. Napišimo zdaj nekaj kode!

Naslednji delček kode prikazuje, kako lahko ustvarite in zaženete 10 niti z uporabo razreda Thread, ki je na voljo v imenskem prostoru System.Threading. Upoštevajte, kako je bil uporabljen delegat ThreadStart.

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

{

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

threadObject.Name = "Ime niti:" + i;

threadObject.Start ();

}

Tu je koda metode PerformSomeWork. To je metoda, ki dejansko vsebuje kodo za delo s semaforji.

zasebna statična praznina PerformSomeWork ()

       {

threadPool.WaitOne ();

Console.WriteLine ("Nit {0} je znotraj kritičnega odseka ...", Thread.CurrentThread.Name);

Navoj.spanje (10000);

threadPool.Release ();

       }

Glejte zgoraj navedeno metodo PerformSomeWork. Metoda WaitOne je poklicana na primerku Semaphore, da blokira trenutno nit, dokler ne prejme signala. Metoda sproščanja se na istem primerku pokliče, da sprosti semafor. Tu je popoln seznam kod za vašo referenco.

razred SemaphoreDemo

   {

javni statični Semaphore threadPool = nov Semaphore (3, 5);

javna statična praznina Main (string [] args)

       {

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

           {

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

threadObject.Name = "Ime niti:" + i;

threadObject.Start ();

           }

Console.ReadLine ();

       }

zasebna statična praznina PerformSomeWork ()

       {

threadPool.WaitOne ();

Console.WriteLine ("Nit {0} je znotraj kritičnega odseka ...", Thread.CurrentThread.Name);

Navoj.spanje (10000);

threadPool.Release ();

       }

   }

$config[zx-auto] not found$config[zx-overlay] not found