Ez a cikk egy tükör gépi fordítás, kérjük, kattintson ide, hogy ugorjon az eredeti cikkre.

Nézet: 46741|Válasz: 7

[Forrás] Volatil vs. Összekapcsolt vs. zár

[Linket másol]
Közzétéve 2018. 08. 27. 14:40:35 | | |
Tegyük fel, hogy van egy olyan osztály, amely tartalmaz egy nyilvános int számláló mezőt, amelyet több szál is elérhető, és ez a szám csak nő vagy csökken.

A mező hozzáadásakor melyik alábbi sémát érdemes használni, és miért?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment (hivatkozás: this.counter);
  • A counter hozzáférési módosítóját public volatile-ra változtasd


A legrosszabb (egyik sem működik igazán)

A counter hozzáférési módosítóját public volatile-ra változtasd

Ez a megközelítés valójában egyáltalán nem biztonságos, és a volatilitás lényege, hogy több szál több CPU-n puffereli az adatokat és átrendezi a végrehajtott utasításokat.

Ha nem volatilis, amikor a CPU A értékkel nő, a CPU B-nek várnia kell egy ideig, hogy lássa a megnövekedett értéket, ami problémákhoz vezethet.

Ha ingadozó, akkor mindkét CPU ugyanazt az értéket látja egyszerre. De nem kerüli el az olvasási és írási műveleteket átvágó műveleteket.

Egy változó értékének hozzáadása valójában három lépést igényel

1. Olvasás, 2. Add hozzá 3. Írj

Tegyük fel, hogy az A szál 1-ként olvassa fel a számláló értékét, és nem áll készen a növekedésre, akkor a B szál is 1-ként olvassa fel a számláló értékét, és mindkét szál elkezd inkrementális és írási műveleteket végrehajtani. A végső számláló értéke 2. Ez nem helyes, mindkét szál végzett egy növelő műveletet, és a helyes eredménynek 3 kell lennie. Tehát a lengőségnek való címkézése egyszerűen veszélyes.

Jobb

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

Így biztonságos (természetesen ne felejtsd el zárni mindenhol, ahol hozzá akarsz férni ehhez a .counterhoz). Ez megakadályozza, hogy bármely más szál végrehajtsa a zárt kódot. Emellett megelőzi a fent említett többprocesszos utasításszekvenálási problémát is. A probléma az, hogy a lock lassú teljesítményű, és ha más, nem kapcsolódó helyeken is használod a lockot, az elzárhatja a többi szálaidat.

Legjobb

Interlocked.Increment (hivatkozás: this.counter);

Ez biztonságos és nagyon hatékony. Egy atomban három olvasási, növelés- és írásműveletet végez anélkül, hogy a közepén megszakítaná. Mivel ez más kódokat nem érint, nem kell máshol zárokat megjegyezned. És nagyon gyors is (ahogy az MSDN mondja, a mai CPU-kon gyakran csak egy utasítás).

De nem vagyok teljesen biztos benne, hogy ez megoldhatja-e a CPU utasítássorrendi problémáját is, vagy szükség van-e a volatile és ezzel a fokozattal együtt használni.

Kiegészítés: Milyen problémákat olda meg jól a volatile?

Mivel a volatile nem tudja megakadályozni a multithreadinget, mit tehet? Jó példa, ha két szálad van, az egyik mindig egy változóhoz ír, tegyük fel, hogy ez a változó queneLength, a másik pedig mindig adatokat olvas ettől a változótól. Ha a queueLenght nem ingadozék, az A szál ötször olvashat, de a B szál késleltetett adatokat vagy akár rossz sorrendben is láthat. Az egyik megoldás a lock használata, de ebben az esetben lehet volatile is használni. Ez biztosítja, hogy a B szál mindig lássa a szál A által írt legfrissebb adatokat, de ez a logika csak akkor működik, ha nem olvasod el az írás közben, és ha nem írod meg, amikor olvasod. Ha több szál olvasás-módosítás-írás műveleteket akar végezni, akkor Interlocked vagy Lock műveleteket kell használni.





Előző:Java MD5 titkosítási módszer
Következő:A Linq nem in és in feltételes lekérdezéseket valósít meg SQL
Közzétéve 2018. 08. 29. 16:21:42 |
Szia, az a kód, amit korábban készítettél, ami a highcharts stacked histogramokat és fúrható hisztogramokat kombinálja? Szeretném megkérdezni, tudsz-e küldeni egy kódot, amit szerkeszteni lehet a https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light felületen?
Közzétéve 2018. 08. 29. 16:22:13 |
Az egész hálózat csak a te erőforrásod.
Közzétéve 2018. 08. 29. 16:22:55 |
Mert az előző 90 évvel ezelőtt nem tudtam üzenetet hagyni. szóval
Közzétéve 2018. 08. 29. 16:40:40 |
Kényelmes kapcsolattartási adatokat adni? Konzultálok veled
 Háziúr| Közzétéve 2018. 09. 15. 13:10:16 |
private statikus int safeInstanceCount = 0; Atomokkal való működés
System.Threading.Interlocked.Increment(ref safeInstanceCount); Önálló növekedés 1
System.Threading.Interlocked.Decrement (ref safeInstanceCount); Önmínusz 1
Közzétéve 2020. 05. 21. 16:43:54 |
Támogassuk a tulajdonost a megosztásra
 Háziúr| Közzétéve 2020. 06. 11. 15:00:16 |
1. Koncepció

Többszálas környezetben olyan műveletek, amelyeket nem szakítanak meg szálütemezési mechanizmusok; Amint ez az operáció elindul, a végéig fut, köztes kontextusváltás (egy másik szálra váltás) nélkül.

2. Osztály

System.Threading.Interlocked statikus osztály

3. Leggyakrabban használt függvények (lásd a többit)

1. nyilvános statikus int Decrement (hivatkozás int hely); A megadott változó értékét atomi művelet formájában decrin és az eredmény tárolása

Ekvivalens a lock(obj){i--; }

2. nyilvános statikus int Increment (hivatkozás int hely); Növeljük a megadott változó értékét atomi művelet formájában, és tároljuk az eredményt

Ekvivalens a lock(obj){i++; }
Lemondás:
A Code Farmer Network által közzétett összes szoftver, programozási anyag vagy cikk kizárólag tanulási és kutatási célokra szolgál; A fenti tartalmat nem szabad kereskedelmi vagy illegális célokra használni, különben a felhasználók viselik az összes következményet. Az oldalon található információk az internetről származnak, és a szerzői jogi vitáknak semmi köze ehhez az oldalhoz. A fenti tartalmat a letöltés után 24 órán belül teljesen törölni kell a számítógépéről. Ha tetszik a program, kérjük, támogassa a valódi szoftvert, vásároljon regisztrációt, és szerezzen jobb hiteles szolgáltatásokat. Ha bármilyen jogsértés történik, kérjük, vegye fel velünk a kapcsolatot e-mailben.

Mail To:help@itsvse.com