Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 46741|Svar: 7

[Källa] Volatile vs. Interlocked vs. lock

[Kopiera länk]
Publicerad på 2018-08-27 14:40:35 | | |
Låt oss säga att det finns en klass som innehåller ett publikt int-räknarfält som kan nås av flera trådar, och detta antal kommer bara att öka eller minska.

När man lägger till detta fält, vilka av följande system bör användas och varför?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Ändra åtkomstmodifieraren för counter till offentlig volatil


Värst (ingen av dem fungerar egentligen)

Ändra åtkomstmodifieraren för counter till offentlig volatil

Denna metod är faktiskt inte alls säker, och poängen med volatile är att flera trådar som körs på flera CPU:er buffrar data och omarrangerar utförda instruktioner.

Om det är icke-flyktigt måste CPU B vänta ett tag när CPU A ökar med ett värde, vilket kan leda till problem.

Om den är volatil säkerställer det att båda CPU:erna ser samma värde samtidigt. Men det undviker inte tvärgående läs- och skrivoperationer.

Att tillföra värde till en variabel tar faktiskt tre steg

1. Läsning, 2. Lägg till 3. Skriv

Antag att tråd A läser värdet på räknaren som 1 och inte är redo att öka, då läser tråd B också värdet på räknaren som 1, och då börjar båda trådarna utföra inkrementella och skrivoperationer. Värdet på den slutliga räknaren är 2. Detta stämmer inte, båda trådarna har gjort en ökningsoperation, och det korrekta resultatet borde vara 3. Så att märka det som flyktigt är helt enkelt osäkert.

Det är bättre

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

På så sätt är det säkert (kom ihåg att låsa överallt där du vill komma åt denna disk, förstås). Det förhindrar att någon annan tråd kan köra den låsta koden. Och det förhindrar också det multi-CPU-instruktionssekvenseringsproblem som nämnts ovan. Problemet är att låsning är långsam i prestanda, och om du använder lås på andra orelaterade ställen kan det blockera dina andra trådar.

Bäst

Interlocked.Increment(ref this.counter);

Detta är säkert och mycket effektivt. Den utför läs-, ökande- och skrivoperationer i en atom utan att avbrytas i mitten. Eftersom det inte påverkar annan kod behöver du inte komma ihåg lås någon annanstans. Och det är också väldigt snabbt (som MSDN säger, på dagens CPU:er är det ofta bara en instruktion).

Men jag är inte helt säker på om det också kan lösa CPU:ns instruktionsordningsproblem, eller om det behöver användas tillsammans med volatile och detta inkrement.

Tillskott: Vilka problem löser flyktigt bra innehåll?

Eftersom Volatile inte kan förhindra multitrådning, vad kan den göra? Ett bra exempel är att du har två trådar, en skriver alltid till en variabel, låt oss säga att denna variabel är queneLength, och den andra läser alltid data från denna variabel. Om queueLenght inte är flyktig kan tråd A läsa 5 gånger, men tråd B kan se fördröjd data, eller till och med data i fel ordning. En lösning är att använda lås, men i det här fallet kan du också använda volatil. Detta säkerställer att tråd B alltid ser den senaste datan skriven av tråd A, men denna logik fungerar bara om du inte läser den när du skriver den, och om du inte skriver den när du läser den. När flera trådar vill göra läs-modifiera-skriv-operationer behöver du använda Interlocked eller lock.





Föregående:Java MD5-krypteringsmetod
Nästa:Linq implementerar inte i och i villkorsförfrågningar i SQL
Publicerad på 2018-08-29 16:21:42 |
Hej, koden du gjorde tidigare som kombinerar högdiagram, staplade histogram och borrbara histogram? Jag skulle vilja fråga om du kan skicka en kod som kan redigeras på https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light-gränssnittet?
Publicerad på 2018-08-29 16:22:13 |
Hela nätverket är bara din resurs.
Publicerad på 2018-08-29 16:22:55 |
För de föregående 90 åren kunde inte lämna ett meddelande. Så
Publicerad på 2018-08-29 16:40:40 |
Är det bekvämt att lägga till kontaktuppgifter? Konsultera dig
 Hyresvärd| Publicerad på 2018-09-15 13:10:16 |
privat statisk int safeInstanceCount = 0; Arbeta med atomer
System.Threading.Interlocked.Increment(ref safeInstanceCount); Självökning 1
System.Threading.Interlocked.Decrement (ref safeInstanceCount); Själv-minus 1
Publicerad på 2020-05-21 16:43:54 |
Stöd ägaren att dela
 Hyresvärd| Publicerad på 2020-06-11 15:00:16 |
1. Koncept

I en multitrådad miljö avbryts operationer som inte avbryts av trådschemaläggningsmekanismer; När denna operation startar körs den till slutet, utan något kontextbyte (byte till en annan tråd) emellan.

2. Klass

System.Threading.Interlocked statisk klass

3. Vanligt förekommande funktioner (se resten)

1. offentlig statisk int-minskning (referens int-plats); Minska värdet på den specificerade variabeln i form av en atomär operation och lagra resultatet

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

2. offentlig statisk int-inkrement(referens int-plats); Öka värdet på den angivna variabeln i form av en atomär operation och lagra resultatet

Ekvivalent med lock(obj){i++; }
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com