Volatile Třída
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Obsahuje metody pro provádění operací nestálé paměti.
public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
- Dědičnost
-
Volatile
Poznámky
V multiprocesorovém systému se může z důvodu optimalizace výkonu v kompilátoru nebo procesoru zdát, že běžné operace paměti se změní, když více procesorů pracuje na stejné paměti. Nestálé paměťové operace zabraňují určitým typům změny pořadí s ohledem na operaci. Nestálé operace zápisu brání dřívějším operacím paměti ve vlákně, aby se přeuspořádaly tak, aby nastaly po nestálém zápisu. Operace nestálého čtení zabraňuje pozdějším operacím paměti ve vlákně, aby se přeuspořádaly před nestálým čtením. Tyto operace můžou u některých procesorů zahrnovat paměťové bariéry, což může mít vliv na výkon.
Představte si například následující scénář se dvěma vlákny a dvěma Int32 poli x
, y
které jsou zpočátku nulové:
Vlákno 1 | Vlákno 2 |
---|---|
x = 1; |
int y2 = Volatile.Read(ref y); |
Volatile.Write(ref y, 1); |
int x2 = x; |
Nestálé čtení a zápis brání změně pořadí dvou operací v rámci každého vlákna, například kompilátorem nebo procesorem. Bez ohledu na pořadí, ve kterém tyto operace skutečně probíhají v jednom vlákně vzhledem k druhému vláknu, a to i v multiprocesorovém systému, kde mohou vlákna běžet na různých procesorech, nestálé operace zaručují, že vlákno 2 neuvidí y2 == 1
a x2 == 0
. Ve vlákně 1 se zápis do x
musí zdát před těkavým zápisem do y
a ve vlákně 2 x
se čtení musí zdát po nestálém čtení .y
Takže pokud vlákno 2 uvidí y2 == 1
, musí také vidět x2 == 1
.
Zvažte ale stejný scénář jako výše s konkrétní sekvencí, ve které k operacím dochází:
Sequence | Vlákno 1 | Vlákno 2 |
---|---|---|
1 | x = 1; |
... |
2 | Volatile.Write(ref y, 1); |
... |
3 | ... |
int y2 = Volatile.Read(ref y); |
4 | ... |
int x2 = x; |
I když těkavý zápis do y
ve vlákně 1 nastal před nestálým čtením y
ve vlákně 2, vlákno 2 může stále vidět y2 == 0
. Volatilní zápis do y
nezaručuje, že následující volatilní čtení y
v jiném procesoru uvidí aktualizovanou hodnotu.
Poznámka
- Nestálé čtení a zápisy zajišťují, že se hodnota načte nebo zapíše do paměti a není uložená v mezipaměti (například v registru procesoru). Tyto operace tedy můžete použít k synchronizaci přístupu k poli, které může být aktualizováno jiným vláknem nebo hardwarem.
- Třída Volatile také poskytuje operace čtení a zápisu pro některé 64bitové typy, jako Int64 jsou a Double. Nestálé čtení a zápisy v této 64bitové paměti jsou atomické i na 32bitových procesorech, na rozdíl od běžných čtení a zápisů.
Operace s nestálou pamětí jsou určené pro zvláštní případy synchronizace, kde normální zamykání není přijatelnou alternativou. Za normálních okolností příkaz jazyka C# lock
, příkaz jazyka Visual Basic SyncLock
a Monitor třída poskytují nejjednodušší a nejméně náchylný způsob synchronizace přístupu k datům a Lazy<T> třída poskytuje jednoduchý způsob psaní opožděného inicializačního kódu bez přímého použití dvojitého zamykání.
Metody Volatile.Read a Volatile.Write umožňují funkce, které nejsou podporovány v jazycích. Příklad:
Některé jazyky, například Visual Basic, nerozpoznávají koncept operací s nestálou pamětí. Třída Volatile poskytuje tuto funkci v těchto jazycích.
Poznámka
Volání jedné z těchto metod ovlivňuje pouze jeden přístup do paměti. Aby byla zajištěna efektivní synchronizace pole, musí veškerý přístup k poli používat Volatile.Read a Volatile.Write.
Použití modifikátoru
volatile
pole v jazyce C# zaručuje, že každý přístup k danému poli je operace nestálé paměti, alevolatile
modifikátor nelze použít na prvky pole. Metody Volatile.Read a Volatile.Write lze použít u prvků pole.
Metody
Read(Boolean) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Byte) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Double) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Int16) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Int32) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Int64) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(IntPtr) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(SByte) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(Single) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(UInt16) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(UInt32) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(UInt64) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read(UIntPtr) |
Načte hodnotu zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Read<T>(T) |
Načte odkaz na objekt ze zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se za touto metodou v kódu zobrazí čtení nebo zápis, procesor jej nemůže přesunout před touto metodou. |
Write(Boolean, Boolean) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Byte, Byte) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Double, Double) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Int16, Int16) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Int32, Int32) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Int64, Int64) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(IntPtr, IntPtr) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(SByte, SByte) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(Single, Single) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(UInt16, UInt16) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(UInt32, UInt32) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(UInt64, UInt64) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write(UIntPtr, UIntPtr) |
Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |
Write<T>(T, T) |
Zapíše zadaný odkaz na objekt do zadaného pole. V systémech, které to vyžadují, vloží paměťovou bariéru, která brání procesoru ve změně pořadí operací paměti následujícím způsobem: Pokud se před touto metodou v kódu objeví čtení nebo zápis, procesor jej nemůže po této metodě přesunout. |