Ohjelmointi

Parhaat käytännöt .Net-ketjujen synkronoinnissa

Synkronointi on käsite, jota käytetään estämään useita ketjuja pääsemästä jaettuun resurssiin samanaikaisesti. Sen avulla voit estää useita ketjuja käyttämästä objektin ominaisuuksia tai menetelmiä samanaikaisesti. Ainoa mitä sinun tarvitsee tehdä, on synkronoida koodilohko, joka käyttää jaettua resurssia, tai synkronoida puhelut objektin ominaisuuksiin ja jäseniin siten, että kulloinkin vain yksi ketju voi päästä kriittiseen osaan.

Tässä artikkelissa esitellään keskustelu synkronointiin ja ketjujen turvallisuuteen liittyvistä käsitteistä .Netissä ja parhaista käytännöistä.

Eksklusiivinen lukko

Eksklusiivista lukitusta käytetään varmistamaan, että yksi ja vain yksi lanka voi päästä kriittiseen osaan. Sinun on käytettävä jotakin seuraavista yksinoikeisten lukkojen toteuttamiseksi sovelluksessasi.

  • Lukitus - tämä on syntaktinen pikakuvake Monitor-luokan staattisille menetelmille ja sitä käytetään yksinoikeuden lukituksen hankkimiseen jaettuun resurssiin
  • Mutex - samanlainen kuin lukitusavainsana paitsi, että se voi toimia useissa prosesseissa
  • SpinLock - käytetään yksinomaisen lukituksen hankkimiseen jaettuun resurssiin välttämällä langan kontekstikytkimen yläpuolella

Voit käyttää Monitor-luokan staattisia menetelmiä tai lukitusavainsanaa säikeiden turvallisuuden varmistamiseksi sovelluksissa. Sekä Monitor-luokan staattisia jäseniä että lukitusavainsanoja voidaan käyttää estämään samanaikainen pääsy jaettuun resurssiin. Lukitusavainsana on vain pikakuvake synkronoinnin toteuttamiseen. Kun sinun on kuitenkin suoritettava monimutkaisia ​​toimintoja monisäikeisessä sovelluksessa, Monitor-luokan Wait () ja Pulse () -menetelmät voivat olla hyödyllisiä.

Seuraava koodinpätkä kuvaa kuinka synkronointi voidaan toteuttaa Monitor-luokan avulla.

yksityinen staattinen vain luettava objekti lockObj = uusi objekti ();

       staattinen void Main (merkkijono [] args)

        {

Näyttö: Syötä (lockObj);

                       yrittää

            {

// Joitakin koodeja

            }

            lopulta

            {

Monitor.Exit (lockObj);

            }

        }

Lukituksen avainsanaa vastaava koodi näyttää tältä:

    yksityinen staattinen vain luettava objekti lockObj = uusi objekti ();

staattinen void Main (merkkijono [] args)

        {  

yrittää

            {

lukko (lockObj)

                {

// Joitakin koodeja

                }             

            }

lopulta

            {

// Voit vapauttaa kaikki resurssit täällä

            }

        }

Voit hyödyntää Mutex-luokkaa synkronoinnin toteuttamiseksi, joka voi ulottua prosessien yli. Huomaa, että samanlainen kuin lukituslauseke, Mutexin hankkima lukko voidaan vapauttaa vain samasta langasta, jota käytettiin lukon hankkimiseen. Lukkojen hankkiminen ja vapauttaminen Mutexin avulla on verrattain hitaampaa kuin saman tekeminen lukituslausekkeen avulla.

SpinLockin pääajatuksena on minimoida kustannukset, jotka aiheutuvat kontekstinvaihdosta ketjujen välillä - jos säie voi odottaa tai pyöriä jonkin aikaa, kunnes se voi hankkia lukituksen jaettuun resurssiin, voidaan välttää kontekstinvaihtoon ketjujen välillä liittyvä yleiskustannus . Kun kriittinen osa suorittaa vähän työtä, se voi olla hyvä ehdokas SpinLockiin.

Ei yksinomainen lukko

Voit hyödyntää ei-yksinomaista lukitusta rajoittaaksesi samanaikaisuutta. Voit käyttää ei-yksinomaisia ​​lukkoja käyttämällä jotakin seuraavista.

  • Semafori - käytetään rajoittamaan ketjujen määrää, joilla voi olla pääsy jaettuun resurssiin samanaikaisesti. Pohjimmiltaan sitä käytetään rajoittamaan tietyn jaetun resurssin kuluttajien määrää samanaikaisesti.
  • SemaphoreSlim - nopea, kevyt vaihtoehto Semaphore-luokalle yksinoikeudella toimivien lukkojen toteuttamiseksi.
  • ReaderWriterLockSlim - ReaderWriterLockSlim-luokka otettiin käyttöön .Net Framework 3.5: ssä ReaderWriterLock-luokan korvikkeena.

ReaderWriterLockSlim-luokan avulla voit hankkia ei-yksinomaisen lukituksen jaetulle resurssille, joka tarvitsee usein lukemia, mutta harvoin päivityksiä. Joten sen sijaan, että jaettu resurssi lukitsisi lukumäärän, joka tarvitsee usein lukemista ja päivityksiä harvoin, voit käyttää tätä luokkaa lukun lukituksen jakamiseen ja yksinoikeudella kirjoituslukkoon.

Umpikujasta

Älä käytä lukituslauseketta tyypissä tai käytä lauseita, kuten lukko (tämä) synkronoinnin toteuttamiseksi sovelluksessasi, koska tämä voi johtaa umpikujaan. Huomaa, että umpikujasta voi syntyä myös, jos pidät jaetusta resurssista hankittua lukkoa pidempään. Älä käytä lukituslausekkeissa muuttumattomia tyyppejä. Esimerkiksi, sinun tulee välttää merkkijono-objektin käyttämistä avaimena lukituslausekkeessa. Sinun tulisi välttää lukituslausekkeen käyttöä julkisessa tyypissä - on hyvä tapa lukita yksityiset tai suojatut objektit, joita ei ole internoitu. Pohjimmiltaan ummetustilanne tapahtuu, kun useat ketjut odottavat toistensa vapauttavan lukituksen jaetulle resurssille. Voit viitata tähän MSDN-artikkeliin saadaksesi lisätietoja umpikujasta.