Programmering

Beste fremgangsmåter for .Net-trådsynkronisering

Synkronisering er et konsept som brukes til å forhindre at flere tråder får tilgang til en delt ressurs samtidig. Du kan bruke den til å forhindre at flere tråder påberoper egenskapene eller metodene til et objekt samtidig. Alt du trenger å gjøre er å synkronisere kodeblokken som får tilgang til den delte ressursen eller synkronisere anropene til egenskapene og medlemmene av objektet, slik at bare en tråd på et gitt tidspunkt kan komme inn i den kritiske delen.

Denne artikkelen presenterer en diskusjon om konseptene knyttet til synkronisering og trådsikkerhet i .Net og de beste fremgangsmåtene som er involvert.

Eksklusiv lås

Eksklusiv låsing brukes til å sikre at en og bare en tråd på et gitt tidspunkt kan komme inn i en kritisk seksjon. Du må bruke ett av følgende for å implementere eksklusive låser i applikasjonen din.

  • Lås - dette er en syntaktisk snarvei for de statiske metodene i Monitor-klassen og brukes til å skaffe en eksklusiv lås på en delt ressurs
  • Mutex - ligner på nøkkelordet, bortsett fra at det kan fungere på tvers av flere prosesser
  • SpinLock - brukes til å skaffe en eksklusiv lås på en delt ressurs ved å unngå trådkontekstbryteren overhead

Du kan bruke de statiske metodene i Monitor-klassen eller låseordet for å implementere trådsikkerhet i applikasjonene dine. Både de statiske medlemmene av klassen Monitor og lås nøkkelordene kan brukes til å forhindre samtidig tilgang til en delt ressurs. Lås nøkkelordet er bare en snarvei for å implementere synkronisering. Men når du trenger å utføre komplekse operasjoner i et flertrådet program, kan metodene Wait () og Pulse () i Monitor-klassen være nyttige.

Følgende kodebit illustrerer hvordan du kan implementere synkronisering ved hjelp av Monitor-klassen.

privat statisk readonly objekt lockObj = nytt objekt ();

       statisk tomrom Main (streng [] args)

        {

Monitor.Enter (lockObj);

                       prøve

            {

// Noe kode

            }

            endelig

            {

Monitor.Exit (lockObj);

            }

        }

Den ekvivalente koden som bruker låseordet, vil se ut som dette:

    privat statisk readonly objektlåsObj = nytt objekt ();

statisk tomrom Main (streng [] args)

        {  

prøve

            {

lås (lockObj)

                {

// Noe kode

                }             

            }

endelig

            {

// Du kan frigjøre eventuelle ressurser her

            }

        }

Du kan dra nytte av Mutex-klassen for å implementere synkronisering som kan strekke seg over prosesser. Vær oppmerksom på at i likhet med låseerklæringen kan en lås anskaffet av en Mutex bare frigjøres fra den samme tråden som ble brukt til å anskaffe låsen. Å anskaffe og frigjøre låser ved hjelp av Mutex er relativt tregere enn å gjøre det samme ved hjelp av låseanmeldelsen.

Hovedideen bak SpinLock er å minimere kostnadene som er involvert i kontekstveksling mellom tråder - hvis en tråd kan vente eller spinne en stund til den kan skaffe seg en lås på en delt ressurs, kan overhead involvert i kontekstbytte mellom tråder unngås . Når den kritiske delen utfører et minimum av arbeid, kan det være en god kandidat for en SpinLock.

Ikke-eksklusiv lås

Du kan dra nytte av ikke-eksklusiv låsing for å begrense samtidigheten. For å implementere ikke-eksklusive låser, kan du bruke ett av følgende.

  • Semaphore - brukes til å begrense antall tråder som kan ha tilgang til en delt ressurs samtidig. I hovedsak brukes den til å begrense antall forbrukere for en bestemt delt ressurs samtidig.
  • SemaphoreSlim - et raskt, lett alternativ til Semaphore-klassen for å implementere ikke-eksklusive låser.
  • ReaderWriterLockSlim - ReaderWriterLockSlim-klassen ble introdusert i .Net Framework 3.5 som erstatning for ReaderWriterLock-klassen.

Du kan bruke ReaderWriterLockSlim-klassen til å skaffe deg en ikke-eksklusiv lås på en delt ressurs som trenger hyppige lesinger, men sjeldne oppdateringer. Så, i stedet for en gjensidig utelukkende lås på en delt ressurs som trenger hyppige lesinger og sjeldne oppdateringer, kan du bruke denne klassen til å skaffe deg en leselås på den delte ressursen og en eksklusiv skrivelås på den.

Låsesperre

Du bør unngå å bruke en låsestatus på typen eller bruke utsagn som lås (dette) for å implementere synkronisering i applikasjonen, da dette kan føre til låsing. Vær oppmerksom på at det også kan oppstå blokkeringer hvis du holder låsen ervervet på en delt ressurs over lengre tid. Du bør ikke bruke uforanderlige typer i låseuttalelsene dine. Som et eksempel, bør du unngå å bruke et strengobjekt som en nøkkel i låseanmeldelsen. Du bør unngå å bruke låseanmeldelsen på en offentlig type - det er en god praksis å låse på private eller beskyttede gjenstander som ikke er internert. I hovedsak oppstår en dødsfallssituasjon når flere tråder venter på at hverandre skal frigjøre lås på en delt ressurs. Du kan referere til denne MSDN-artikkelen for å vite mer om fastlåste forhold.

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