Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 46741|Odpověď: 7

[Zdroj] Volatile vs. Interlocked vs. lock

[Kopírovat odkaz]
Zveřejněno 27.08.2018 14:40:35 | | |
Řekněme, že existuje třída, která obsahuje veřejné pole čítače int, ke kterému může přistupovat více vláken, a toto číslo se bude jen zvyšovat nebo snižovat.

Při přidávání tohoto pole, které z následujících schémat by měly být použity a proč?

  • lock(this.locker) this.counter++;
  • Propojené. Postupné (odkaz na toto.čítač);
  • Změňte přístupový modifikátor counter na public volatile


Nejhorší (žádná z nich vlastně nefunguje)

Změňte přístupový modifikátor counter na public volatile

Tento přístup není vůbec bezpečný a smyslem volatile je, že více vláken běžících na více CPU uchovává data v bufferu a přeskupuje vykonávané instrukce.

Pokud je nevolatilní, když CPU A vzroste o hodnotu, CPU B musí chvíli počkat, než se hodnota zvýší, což může vést k problémům.

Pokud je volatilní, zajistí, že oba CPU vidí stejnou hodnotu současně. Ale nevyhne se průřezovým operacím čtení a zápisu.

Přidání hodnoty proměnné ve skutečnosti vyžaduje tři kroky

1. Čtení, 2. Přičíst 3. Napsat

Předpokládejme, že vlákno A čte hodnotu čítače jako 1 a není připraveno k navýšení, pak vlákno B také čte hodnotu čítače jako 1, a obě vlákna začnou provádět inkrementální a zápisové operace. Hodnota posledního žetonu je 2. To není správné, obě vlákna provedla operaci zvyšování a správný výsledek by měl být 3. Takže označovat ho jako volatilní je prostě nebezpečné.

Je to lepší

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

Tímto způsobem je to bezpečné (nezapomeňte zamknout všechna místa, kde chcete přistupovat k tomuto pultu, samozřejmě). Zabraňuje tomu, aby jakékoli jiné vlákno mohlo vykonat zamčený kód. A také zabraňuje problému s řadou instrukcí více CPU, který byl zmíněn výše. Problém je, že zámek je pomalý ve výkonu, a pokud použijete zámek na jiných nesouvisejících místech, může blokovat vaše ostatní vlákna.

Nejlepší

Propojené. Postupné (odkaz na toto.čítač);

To je bezpečné a velmi efektivní. Provádí čtení, zvyšování a zápis tří operací v jednom atomu bez přerušení uprostřed. Protože to neovlivňuje jiný kód, nemusíte si zámky pamatovat jinde. A je také velmi rychlý (jak říká MSDN, na dnešních CPU je to často jen instrukce).

Ale nejsem si úplně jistý, jestli to může vyřešit i problém s pořadím instrukcí CPU, nebo jestli je potřeba to používat společně s Volatile a tímto inkrementem.

Doplněk: Jaké problémy Volatile řeší dobře?

Jelikož Volatile nemůže zabránit vícevláknovému zpracování, co dokáže? Dobrým příkladem jsou dvě vlákna, jedno vždy zapisuje do proměnné, řekněme, že tato proměnná je queneLength, a druhé vždy čte data z této proměnné. Pokud délka fronty není volatilní, vlákno A může číst 5krát, ale vlákno B může vidět zpožděná data, nebo dokonce data v nesprávném pořadí. Jedním řešením je použít zámek, ale v tomto případě můžete použít i volatile. To zajišťuje, že vlákno B vždy vidí nejnovější data napsaná vláknem A, ale tato logika funguje jen tehdy, pokud je při zápisu nečtete a když je nezapisujete. Jakmile chce více vláken provádět operace čtení-úprava-zápis, je potřeba použít Interlocked nebo lock.





Předchozí:Metoda šifrování Java MD5
Další:Linq implementuje ne v a v podmíněných dotazech v SQL
Zveřejněno 29.08.2018 16:21:42 |
Ahoj, ten kód, který jsi dělal dříve a který kombinuje highcharty složené histogramy a drillable histogramy? Chtěl bych se zeptat, jestli můžete poslat kód, který lze upravit na https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light rozhraní?
Zveřejněno 29.08.2018 16:22:13 |
Celá síť je jen váš zdroj.
Zveřejněno 29.08.2018 16:22:55 |
Protože předchozích 90 let nemohlo zanechat vzkaz. takže
Zveřejněno 29.08.2018 16:40:40 |
Je pohodlné přidat kontaktní údaje? Poradit se s vámi
 Pronajímatel| Zveřejněno 15.09.2018 13:10:16 |
soukromý statický int safeInstanceCount = 0; Pracuj s atomy
System.Threading.Interlocked.Increment(ref safeInstanceCount); Samo-zvyšování 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Self-minus 1
Zveřejněno 21.05.2020 16:43:54 |
Podpořte vlastníka při sdílení
 Pronajímatel| Zveřejněno 11.06.2020 15:00:16 |
1. Koncept

V prostředí s více vlákny operace, které nejsou přerušeny mechanismy plánování vláken; Jakmile tato operace začne, běží až do konce, bez jakéhokoliv přepnutí kontextu (přepnutí na jiné vlákno) mezi tím.

2. Třída

System.Threading.Interlocked statická třída

3. Běžně používané funkce (viz zbytek)

1. veřejný statický int Dékrement (ref int location); Decrujte hodnotu dané proměnné ve formě atomové operace a uložte výsledek

Ekvivalent lock(obj){i--; }

2. veřejný statický inkrement (odkaz na polohu); Zvyšte hodnotu specifikované proměnné ve formě atomové operace a uložte výsledek

Ekvivalentní lock(obj){i++; }
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com