Denne artikel er en spejling af maskinoversættelse, klik venligst her for at springe til den oprindelige artikel.

Udsigt: 46741|Svar: 7

[Kilde] Volatile vs. Interlocked vs. lock

[Kopier link]
Opslået på 27/08/2018 14.40.35 | | |
Lad os sige, at der findes en klasse, der indeholder et offentligt int-tællefelt, som kan tilgås af flere tråde, og dette tal kun vil stige eller falde.

Når man tilføjer dette felt, hvilke af følgende skemaer bør så bruges, og hvorfor?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Skift adgangsmodifikatoren for counter til offentlig volatil


Værst (ingen af dem virker egentlig)

Skift adgangsmodifikatoren for counter til offentlig volatil

Denne tilgang er faktisk slet ikke sikker, og pointen med Volatile er, at flere tråde, der kører på flere CPU'er, buffer data og omarrangerer udførte instruktioner.

Hvis den er ikke-flygtig, skal CPU B vente et stykke tid for at se den øgede værdi, når CPU A stiger med en værdi, hvilket kan føre til problemer.

Hvis det er flygtigt, sikrer det, at begge CPU'er ser samme værdi på samme tid. Men det undgår ikke tværgående læse- og skriveoperationer.

At tilføre værdi til en variabel kræver faktisk tre trin

1. Læsning, 2. Tilføj 3. Skriv

Antag, at tråd A læser værdien af tælleren som 1 og ikke er klar til at øge, så læser tråd B også værdien af tælleren som 1, og så begynder begge tråde at udføre inkrementelle og skriveoperationer. Værdien af den endelige tæller er 2. Det er ikke korrekt, begge tråde har udført en forøgelsesoperation, og det korrekte resultat burde være 3. Så at mærke det som flygtigt er simpelthen usikkert.

Det er bedre

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

På den måde er det sikkert (husk selvfølgelig at låse overalt, hvor du vil have adgang til denne disk). Det forhindrer andre tråde i at udføre den låste kode. Og det forhindrer også problemet med multi-CPU instruktionssekventering nævnt ovenfor. Problemet er, at lock er langsom i ydeevnen, og hvis du bruger lock andre steder, der ikke er relateret, kan det blokere dine andre tråde.

Bedst

Interlocked.Increment(ref this.counter);

Det er sikkert og meget effektivt. Den udfører læse-, øgnings- og skriveoperationer i ét atom uden at blive afbrudt midt imellem. Fordi det ikke påvirker anden kode, behøver du ikke huske låse andre steder. Og det er også meget hurtigt (som MSDN siger, er det på nutidens CPU'er ofte bare en instruktion).

Men jeg er ikke helt sikker på, om det også kan løse CPU'ens instruktionsordensproblem, eller om det skal bruges sammen med volatile og dette inkrement.

Supplement: Hvilke problemer løser volatile godt?

Da Volatile ikke kan forhindre multithreading, hvad kan den så gøre? Et godt eksempel er, at du har to tråde, den ene skriver altid til en variabel, lad os sige, at denne variabel er queneLength, og den anden læser altid data fra denne variabel. Hvis queueLenght ikke er flygtig, kan tråd A læse 5 gange, men tråd B kan se forsinkede data eller endda data i forkert rækkefølge. En løsning er at bruge lock, men i dette tilfælde kan du også bruge volatile. Dette sikrer, at tråd B altid ser de seneste data skrevet af tråd A, men denne logik virker kun, hvis du ikke læser den, når du skriver den, og hvis du ikke skriver den, når du læser den. Når flere tråde vil udføre læs-ændre-skrive-operationer, skal du bruge Interlocked eller lock.





Tidligere:Java MD5-krypteringsmetode
Næste:Linq implementerer ikke i og i betingede forespørgsler i SQL
Opslået på 29/08/2018 16.21.42 |
Hej, koden du lavede tidligere, som kombinerer highcharts, stablede histogrammer og drillbare histogrammer? Jeg vil gerne spørge, om du kan sende en kode, der kan redigeres på https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light-interfacet?
Opslået på 29/08/2018 16.22.13 |
Hele netværket er bare din ressource.
Opslået på 29/08/2018 16.22.55 |
For de foregående 90 år siden kunne ikke efterlade en besked. Så
Opslået på 29/08/2018 16.40.40 |
Er det praktisk at tilføje kontaktoplysninger? Rådføre mig med dig
 Udlejer| Opslået på 15/09/2018 13.10.16 |
privat statisk int safeInstanceCount = 0; Operer med atomer
System.Threading.Interlocked.Increment(ref safeInstanceCount); Selvforøgelse 1
System.Threading.Interlocked.Decrement (ref safeInstanceCount); Selv-minus 1
Opslået på 21/05/2020 16.43.54 |
Støt ejeren i at dele
 Udlejer| Opslået på 11/06/2020 15.00.16 |
1. Koncept

I et multitrådet miljø afbrydes operationer, der ikke afbrydes af trådplanlægningsmekanismer; Når denne operation starter, kører den til slutningen, uden nogen kontekstskift (skift til en anden tråd) imellem.

2. Klasse

System.Threading.Interlocked statisk klasse

3. Almindeligt anvendte funktioner (se resten)

1. offentlig statisk int Decrement (ref int placering); Reducer værdien af den specificerede variabel i form af en atomar operation og gem resultatet

Ækvivalent med lock(obj){i--; }

2. offentlig statisk int Increment (ref int lokation); Øg værdien af den specificerede variabel i form af en atomar operation og gem resultatet

Ækvivalent med lock(obj){i++; }
Ansvarsfraskrivelse:
Al software, programmeringsmaterialer eller artikler udgivet af Code Farmer Network er kun til lærings- og forskningsformål; Ovenstående indhold må ikke bruges til kommercielle eller ulovlige formål, ellers skal brugerne bære alle konsekvenser. Oplysningerne på dette site kommer fra internettet, og ophavsretstvister har intet med dette site at gøre. Du skal slette ovenstående indhold fuldstændigt fra din computer inden for 24 timer efter download. Hvis du kan lide programmet, så understøt venligst ægte software, køb registrering og få bedre ægte tjenester. Hvis der er nogen overtrædelse, bedes du kontakte os via e-mail.

Mail To:help@itsvse.com