Najbolji primjeri za sinkronizaciju niti .Net

Sinkronizacija je koncept koji se koristi za sprečavanje istodobnog pristupa više niti pomoću zajedničkog resursa. Pomoću nje možete spriječiti da više niti istodobno poziva svojstva ili metode objekta. Sve što trebate je sinkronizirati blok koda koji pristupa zajedničkom resursu ili sinkronizirati pozive svojstvima i članovima objekta tako da u bilo kojem trenutku samo jedna nit može ući u kritični odjeljak.

Ovaj članak predstavlja raspravu o konceptima povezanim sa sinkronizacijom i sigurnošću niti u .Netu i najboljim uključenim praksama.

Ekskluzivna brava

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. Za primjenu ekskluzivnih brava u svojoj aplikaciji morate koristiti jedno od sljedećeg.

  • Zaključaj - ovo je sintaksički prečac za statičke metode klase Monitor i koristi se za stjecanje ekskluzivnog zaključavanja zajedničkog resursa
  • Mutex - sličan ključnoj riječi lock, osim što može raditi u više procesa
  • SpinLock - koristi se za stjecanje ekskluzivne brave na zajedničkom resursu izbjegavanjem preklapanja konteksta niti iznad glave

Možete primijeniti statičke metode klase Monitor ili ključnu riječ lock da biste implementirali sigurnost niti u svoje aplikacije. I statični članovi klase Monitor i ključne riječi lock mogu se koristiti za sprečavanje istodobnog pristupa zajedničkom resursu. Ključna riječ lock samo je prečac za provedbu sinkronizacije. Međutim, kada trebate izvoditi složene operacije u višenitnoj aplikaciji, metode Wait () i Pulse () klase Monitor mogu biti korisne.

Sljedeći isječak koda ilustrira kako možete implementirati sinkronizaciju pomoću klase Monitor.

private static readonly object lockObj = new object();

        static void Main(string[] args)

        {

            Monitor.Enter(lockObj);

                       try

            {

               //Some code

            }

                  finally

            {

                Monitor.Exit(lockObj);

            }

        }

Ekvivalentni kod koji koristi ključnu riječ lock izgledat će slično ovome:

    private static readonly object lockObj = new object();

        static void Main(string[] args)

        {  

            try

            {

                lock(lockObj)

                {

                    //Some code

                }             

            }

            finally

            {

                //You can release any resources here

            }

        }

Možete iskoristiti klasu Mutex za implementaciju sinkronizacije koja se može proširiti na sve procese. Imajte na umu da se slično izjavi zaključavanja, brava koju je stekao Mutex može osloboditi samo iz iste niti koja je korištena za dobivanje brave. Pribavljanje i oslobađanje brava pomoću Mutexa usporedno je sporije od činjenja istog pomoću izraza zaključavanje.

Glavna ideja koja stoji iza SpinLocka je minimiziranje troškova uključenih u prebacivanje konteksta između niti - ako nit može neko vrijeme čekati ili se vrtjeti dok ne dobije zaključavanje na zajedničkom resursu, može se izbjeći preopterećenje uključeno u prebacivanje konteksta između niti . Kada kritični dio izvede minimalnu količinu posla, to može biti dobar kandidat za SpinLock.

Neekskluzivna brava

Možete iskoristiti neekskluzivno zaključavanje kako biste ograničili istodobnost. Da biste primijenili neekskluzivne brave, možete koristiti jedno od sljedećeg.

  • Semafor - koristi se 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.
  • SemaphoreSlim - brza, lagana alternativa klasi Semaphore za primjenu neekskluzivnih brava.
  • ReaderWriterLockSlim - klasa ReaderWriterLockSlim uvedena je u .Net Framework 3.5 kao zamjena za klasu ReaderWriterLock.

Klasu ReaderWriterLockSlim možete koristiti za stjecanje neekskluzivnog zaključavanja zajedničkog resursa kojemu su potrebna česta čitanja, ali rijetka ažuriranja. Dakle, umjesto međusobno isključivog zaključavanja zajedničkog resursa kojem su potrebna česta čitanja i rijetka ažuriranja, ovu klasu možete upotrijebiti za stjecanje zaključavanja čitanja zajedničkog resursa i ekskluzivnog zaključavanja pisanja na njemu.

Zastoji

Trebali biste izbjegavati upotrebu naredbe lock na tipu ili koristiti naredbe poput lock (this) da biste implementirali sinkronizaciju u svojoj aplikaciji jer bi to moglo dovesti do zastoja. Imajte na umu da se mrtve točke mogu pojaviti i ako duže vrijeme držite zaključavanje stečeno na zajedničkom resursu. U izjavama zaključavanja ne biste trebali koristiti nepromjenjive vrste. Kao primjer, trebali biste izbjegavati upotrebu niza kao ključa u izjavi zaključavanja. Trebali biste izbjegavati upotrebu izjave zaključavanja na javnom tipu - dobra je praksa zaključavanje privatnih ili zaštićenih objekata koji nisu internirani. U osnovi se događa mrtva situacija kada više niti čeka međusobno oslobađanje zaključavanja na zajedničkom resursu. Možete se pozvati na ovaj članak o MSDN-u da biste saznali više o zastojima.