Volatile Třída

Definice

Obsahuje metody pro provádění nestálých paměťových operací.

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 kvůli optimalizaci výkonu kompilátoru nebo procesoru může stát, že se běžné operace paměti změní, když na stejné paměti pracuje více procesorů. Nestálá paměťová operace brání určitým typům změny pořadí s ohledem na operaci. Volatilní operace zápisu zabraňuje dřívějším operacím paměti ve vlákně, aby došlo k přeuspořádaní po nestálém zápisu. Volatilní operace čtení zabraňuje pozdějším operacím paměti ve vlákně, aby došlo ke změnám pořadí před nestálým čtením. Tyto operace můžou zahrnovat bariéry paměti u některých procesorů, které můžou ovlivnit výkon.

Představte si například následující scénář se dvěma vlákny a dvěma Int32 poli x a y počáteční nulou:

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ěny 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 se tyto operace skutečně vyskytují v jednom vlákně vzhledem k druhému vláknu, i v multiprocesorovém systému, kde mohou vlákna běžet na různých procesorech, volatilní operace zaručit, že vlákno 2 neuvidí y2 == 1 a x2 == 0. Na vlákně 1 se zápis x musí objevit před těkavý zápis do y, a na vlákně 2 x čtení musí dojít po nestálém yčtení . 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 na y vlákno 1 došlo před těkavý čtením y ve vlákně 2, vlákno 2 může stále vidět y2 == 0. Nestálý zápis y nezaručuje, že se aktualizovaná hodnota zobrazí v jiném procesoru následující nestálé čtení y .

Note

  • Nestálé čtení a zápisy zajišťují, že je hodnota přečtená nebo zapsaná do paměti a že 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é lze aktualizovat jiným vláknem nebo hardwarem.
  • Třída Volatile také poskytuje operace čtení a zápisu pro některé 64bitové typy, jako Int64Doubleje a . Nestálé čtení a zápisy v takové 64bitové paměti jsou atomické i na 32bitových procesorech, na rozdíl od běžných čtení a zápisů.

Nestálá paměťová operace jsou určené pro zvláštní případy synchronizace, kdy normální uzamykání není přijatelnou alternativou. Za normálních okolností poskytuje příkaz C# lock, příkaz Visual Basic SyncLock a třída Monitor nejjednodušší a nejméně chybový způsob synchronizace přístupu k datům a třída Lazy<T> jednoduchý způsob psaní opožděného inicializačního kódu bez přímého použití dvojité kontroly zamykání.

Funkce Volatile.Read , které nejsou podporované v jazycích, a Volatile.Write metody umožňují. Příklad:

  • Některé jazyky, například Visual Basic, nerozpoznávají koncept nestálých operací paměti. Třída Volatile poskytuje tyto funkce v takových jazycích.

    Note

    Volání jedné z těchto metod ovlivňuje pouze jeden přístup k paměti. Aby bylo možné zajistit efektivní synchronizaci pro pole, musí Volatile.Read být použit veškerý přístup k poli a Volatile.Write.

  • Použití modifikátoru volatile v jazyce C# u pole zaručuje, že každý přístup k danému poli je nestálá paměťová operace, ale volatile modifikátor nelze použít u prvků pole. Tyto Volatile.Read metody Volatile.Write lze použít u prvků pole.

Metody

Name Description
Read(Boolean)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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)

Přečte hodnotu zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání 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ží bariéru paměti, která brání procesoru v uspořádání 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.

ReadBarrier()

Synchronizuje přístup k paměti následujícím způsobem:

Procesor, který spouští aktuální vlákno, nemůže změnit pořadí instrukcí tak, aby paměť četla před voláním, aby se ReadBarrier() spustila po přístupu k paměti, které následují za voláním ReadBarrier().

Write(Boolean, Boolean)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Byte, Byte)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Double, Double)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Int16, Int16)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Int32, Int32)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Int64, Int64)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(IntPtr, IntPtr)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(SByte, SByte)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(Single, Single)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(UInt16, UInt16)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(UInt32, UInt32)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(UInt64, UInt64)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write(UIntPtr, UIntPtr)

Zapíše zadanou hodnotu do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

Write<T>(T, T)

Zapíše zadaný odkaz na objekt do zadaného pole. V systémech, které to vyžadují, vloží bariéru paměti, která brání procesoru v uspořádání operací paměti následujícím způsobem: Pokud se před touto metodou v kódu zobrazí operace čtení nebo zápisu, procesor jej po této metodě nemůže přesunout.

WriteBarrier()

Synchronizuje přístup k paměti následujícím způsobem:

Procesor, který spouští aktuální vlákno, nemůže změnit pořadí instrukcí tak, aby paměť zapisuje po volání WriteBarrier() provést před přístupem k paměti, které předchází volání WriteBarrier().

Platí pro

Viz také