Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 46741|Svare: 7

[Kilde] Volatile vs. Interlocked vs. lock

[Kopier lenke]
Publisert på 27.08.2018 14:40:35 | | |
La oss si at det finnes en klasse som inneholder et offentlig int-tellerfelt som kan nås av flere tråder, og dette tallet vil bare øke eller synke.

Når man legger til dette feltet, hvilke av følgende skjemaer bør brukes, og hvorfor?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment (ref this.counter);
  • Endre tilgangsmodifikatoren til counter til offentlig volatil


Verst (ingen av dem fungerer egentlig)

Endre tilgangsmodifikatoren til counter til offentlig volatil

Denne tilnærmingen er faktisk ikke sikker i det hele tatt, og poenget med Volatile er at flere tråder som kjører på flere CPU-er buffrer data og omorganiserer utførte instruksjoner.

Hvis den er ikke-flyktig, må CPU B vente en stund for å se den økte verdien når CPU A øker med en verdi, noe som kan føre til problemer.

Hvis den er flyktig, sikrer det at begge CPU-ene ser samme verdi samtidig. Men det unngår ikke tverrgående lese- og skriveoperasjoner.

Å tilføre verdi til en variabel krever faktisk tre steg

1. Lesing, 2. Legg til 3. Skriv

Anta at tråd A leser verdien av telleren som 1 og ikke er klar til å øke, så leser tråd B også verdien av telleren som 1, og så begynner begge trådene å utføre inkrementelle og skriveoperasjoner. Verdien av den endelige telleren er 2. Dette stemmer ikke, begge trådene har utført en økningsoperasjon, og det riktige resultatet skal være 3. Så å merke det som flyktig er rett og slett utrygt.

Det er bedre

lock(this.locker) this.counter++;

På denne måten er det trygt (husk å låse overalt du vil for å få tilgang til denne disken, selvfølgelig). Den forhindrer at andre tråder kjører den låste koden. Og det forhindrer også problemet med multi-CPU-instruksjonssekvensering nevnt ovenfor. Problemet er at lås er treg i ytelsen, og hvis du bruker lås på andre, ikke-relaterte steder, kan det blokkere de andre trådene dine.

Best

Interlocked.Increment (ref this.counter);

Dette er trygt og veldig effektivt. Den utfører lesing, økning, skriving tre operasjoner i ett atom uten å bli avbrutt i midten. Fordi det ikke påvirker annen kode, trenger du ikke huske låser andre steder. Og det er også veldig raskt (som MSDN sier, på dagens CPU-er er det ofte bare en instruksjon).

Men jeg er ikke helt sikker på om det også kan løse CPU-ens instruksjonsrekkefølgeproblem, eller om det må brukes sammen med volatile og dette inkrementet.

Supplement: Hvilke problemer løser volatile godt?

Siden Volatile ikke kan forhindre multitråding, hva kan den gjøre? Et godt eksempel er at du har to tråder, den ene skriver alltid til en variabel, la oss si at denne variabelen er queneLength, og den andre leser alltid data fra denne variabelen. Hvis queueLenght ikke er flyktig, kan tråd A lese 5 ganger, men tråd B kan se forsinket data, eller til og med data i feil rekkefølge. En løsning er å bruke lock, men i dette tilfellet kan du også bruke volatile. Dette sikrer at tråd B alltid ser de nyeste dataene skrevet av tråd A, men denne logikken fungerer bare hvis du ikke leser det når du skriver det, og hvis du ikke skriver det når du leser det. Når flere tråder vil utføre lese-modifiser-skrive-operasjoner, må du bruke Interlocked eller lock.





Foregående:Java MD5-krypteringsmetode
Neste:Linq implementerer ikke i og i betingede spørringer i SQL
Publisert på 29.08.2018 16:21:42 |
Hei, koden du laget tidligere som kombinerer høydiagrammer, stablede histogrammer og drillbare histogrammer? Jeg vil gjerne spørre om du kan sende en kode som kan redigeres på https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light-grensesnittet?
Publisert på 29.08.2018 16:22:13 |
Hele nettverket er bare din ressurs.
Publisert på 29.08.2018 16:22:55 |
Fordi de foregående 90 årene siden ikke kunne legge igjen en beskjed. Så
Publisert på 29.08.2018 16:40:40 |
Er det praktisk å legge til kontaktinformasjon? Rådføre meg med deg
 Vert| Publisert på 15.09.2018 13:10:16 |
privat statisk int safeInstanceCount = 0; Operer med atomer
System.Threading.Interlocked.Increment(ref safeInstanceCount); Selvøkning 1
System.Threading.Interlocked.Decrement (ref safeInstanceCount); Selv-minus 1
Publisert på 21.05.2020 16:43:54 |
Støtt eieren i å dele
 Vert| Publisert på 11.06.2020 15:00:16 |
1. Konsept

I et flertrådet miljø, operasjoner som ikke avbrytes av trådplanleggingsmekanismer; Når denne operasjonen starter, kjører den til slutten, uten noen kontekstbytte (bytte til en annen tråd) imellom.

2. Klasse

System.Threading.Interlocked statisk klasse

3. Vanlig brukte funksjoner (se resten)

1. offentlig statisk int Decrement (referanse int lokasjon); Trekk verdien av den spesifiserte variabelen i form av en atomoperasjon og lagre resultatet

Ekvivalent med lock(obj){i--; }

2. offentlig statisk int Increment (ref int lokasjon); Øk verdien av den spesifiserte variabelen i form av en atomoperasjon og lagre resultatet

Ekvivalent med lock(obj){i++; }
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com