Ta članek je zrcalni članek strojnega prevajanja, kliknite tukaj za skok na izvirni članek.

Pogled: 46741|Odgovoriti: 7

[Vir] Volatile vs. Interlocked vs. lock

[Kopiraj povezavo]
Objavljeno na 27. 08. 2018 14:40:35 | | |
Recimo, da obstaja razred, ki vsebuje javno polje števca int, do katerega lahko dostopa več niti, in to število se bo samo povečevalo ali zmanjševalo.

Pri dodajanju tega polja, katere od naslednjih shem naj uporabimo in zakaj?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment (ref this.counter);
  • Spremeni modifikator dostopa v counter na javno volatile


Najslabše (nobena od njih dejansko ne deluje)

Spremeni modifikator dostopa v counter na javno volatile

Ta pristop pravzaprav sploh ni varen, in bistvo volatile je, da več niti, ki tečejo na več procesorjih, medpomnijo podatke in preurejajo izvedene ukaze.

Če je nehlapna, mora CPU B počakati nekaj časa, ko CPU A poveča vrednost, kar lahko povzroči težave.

Če je hlapna, zagotavlja, da oba procesorja hkrati zaznata enako vrednost. Vendar pa ne preprečuje presečnih operacij branja in pisanja.

Dodajanje vrednosti spremenljivki dejansko zahteva tri korake

1. Branje, 2. Dodaj 3. Napiši

Predpostavimo, da nit A prebere vrednost števca kot 1 in ni pripravljena povečati, potem nit B prav tako prebere vrednost števca kot 1, nato pa obe niti začneta izvajati inkrementalne in zapisovalne operacije. Vrednost zadnjega števca je 2. To ni pravilno, obe niti sta izvedli operacijo povečanja, pravilen rezultat pa bi moral biti 3. Torej je označevanje kot hlapnega preprosto nevarno.

Tako je bolje

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

Tako je varno (seveda ne pozabite zakleniti povsod, kjer želite dostopati do tega pulta). Preprečuje, da bi katera koli druga nit izvajala zaklenjeno kodo. Prav tako preprečuje težave z zaporedjem ukazov z več procesorji, omenjene zgoraj. Težava je v tem, da je zaklepanje počasno v zmogljivosti, in če zaklepate na drugih nepovezanih mestih, lahko blokira druge niti.

Najboljše

Interlocked.Increment (ref this.counter);

To je varno in zelo učinkovito. Izvaja tri operacije branja, povečanja in pisanja v enem atomu brez prekinitve na sredini. Ker to ne vpliva na drugo kodo, ti ni treba zapomniti ključavnic drugje. Poleg tega je zelo hiter (kot pravi MSDN, je na današnjih procesorjih pogosto le ukaz).

Nisem pa povsem prepričan, ali lahko to reši tudi težavo z vrstnim redom ukazov procesorja ali pa ga je treba uporabljati skupaj s Volatile in tem inkrementom.

Dodatek: Katere probleme Volatile dobro rešuje?

Ker Volatile ne more preprečiti večnitnosti, kaj lahko stori? Dober primer je, da imate dve niti, ena vedno piše v spremenljivko, recimo, da je ta spremenljivka queneLength, druga pa vedno bere podatke iz te spremenljivke. Če dolžina čakalne vrste ni nestanovitna, lahko nit A bere 5-krat, nit B pa lahko zazna zamujene podatke ali celo podatke v napačnem vrstnem redu. Ena rešitev je uporaba zaklepanja, v tem primeru pa lahko uporabite tudi volatile. To zagotavlja, da nit B vedno vidi najnovejše podatke, ki jih je zapisala nit A, vendar ta logika deluje le, če jih ne berete med pisanjem in če jih ne zapišete ob branju. Ko več niti želi izvajati operacije branja, spreminjanja in pisanja, morate uporabiti Interlocked ali lock.





Prejšnji:Java MD5 metoda šifriranja
Naslednji:Linq implementira ne v in v pogojnih poizvedbah v SQL
Objavljeno na 29. 08. 2018 16:21:42 |
Pozdravljeni, tista koda, ki si jo prej naredil in združuje visoke grafikone, zložene histograme in drillable histograme? Rad bi vprašal, ali lahko pošljete kodo, ki jo je mogoče urediti na https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light vmesniku?
Objavljeno na 29. 08. 2018 16:22:13 |
Celotno omrežje je le tvoj vir.
Objavljeno na 29. 08. 2018 16:22:55 |
Ker prejšnjih 90 let ni moglo pustiti sporočila. torej
Objavljeno na 29. 08. 2018 16:40:40 |
Ali je priročno dodati kontaktne podatke? Posvetujem se z vami
 Najemodajalec| Objavljeno na 15. 09. 2018 13:10:16 |
private static int safeInstanceCount = 0; Delaj z atomi
System.Threading.Interlocked.Increment(ref safeInstanceCount); Samopovečanje 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Samo-minus 1
Objavljeno na 21. 05. 2020 16:43:54 |
Podprite lastnika pri deljenju
 Najemodajalec| Objavljeno na 11. 06. 2020 15:00:16 |
1. Koncept

V večnitnem okolju operacije, ki jih mehanizmi razporejanja niti ne prekinjajo; Ko se ta operacija začne, teče do konca, brez kakršnegakoli preklopa konteksta (preklop na drugo nit) vmes.

2. Razred

System.Threading.Interlocked statični razred

3. Pogosto uporabljene funkcije (glej ostalo)

1. javni statični int Decrement (ref int location); Vrednost določene spremenljivke decrirajte v obliki atomske operacije in shranite rezultat

Ekvivalent lock(obj){i--; }

2. javni statični inkrement (ref int location); Povečajte vrednost določene spremenljivke v obliki atomske operacije in shranite rezultat

Ekvivalent lock(obj){i++; }
Disclaimer:
Vsa programska oprema, programski materiali ali članki, ki jih izdaja Code Farmer Network, so namenjeni zgolj učnim in raziskovalnim namenom; Zgornja vsebina ne sme biti uporabljena v komercialne ali nezakonite namene, sicer uporabniki nosijo vse posledice. Informacije na tej strani prihajajo z interneta, spori glede avtorskih pravic pa nimajo nobene zveze s to stranjo. Zgornjo vsebino morate popolnoma izbrisati z računalnika v 24 urah po prenosu. Če vam je program všeč, podprite pristno programsko opremo, kupite registracijo in pridobite boljše pristne storitve. Če pride do kakršne koli kršitve, nas prosimo kontaktirajte po elektronski pošti.

Mail To:help@itsvse.com