Volatile Klasa

Definicja

Zawiera metody wykonywania nietrwałych operacji pamięci.

public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
Dziedziczenie
Volatile

Uwagi

W systemie wieloprocesorowym ze względu na optymalizacje wydajności w kompilatorze lub procesorze regularne operacje pamięci mogą wydawać się zmieniane, gdy wiele procesorów działa na tej samej pamięci. Nietrwałe operacje pamięci zapobiegają niektórym typom zmiany kolejności w odniesieniu do operacji. Nietrwała operacja zapisu uniemożliwia wcześniejsze operacje pamięci w wątku, które mają być zmieniane po zapisie nietrwałym. Nietrwała operacja odczytu uniemożliwia późniejsze operacje na pamięci w wątku, które mają być zmieniane przed odczytem nietrwałym. Te operacje mogą obejmować bariery pamięci w niektórych procesorach, co może mieć wpływ na wydajność.

Rozważmy na przykład następujący scenariusz z dwoma wątkami i dwoma Int32 polami x , y które początkowo są zerowe:

Wątek 1 Wątek 2
x = 1; int y2 = Volatile.Read(ref y);
Volatile.Write(ref y, 1); int x2 = x;

Nietrwałe operacje odczytu i zapisu uniemożliwiają zmiana kolejności dwóch operacji w każdym wątku, takich jak kompilator lub procesor. Niezależnie od kolejności, w jakiej te operacje rzeczywiście występują w jednym wątku względem drugiego wątku, nawet w systemie wieloprocesorowym, w którym wątki mogą być uruchamiane na różnych procesorach, operacje lotne gwarantują, że wątek 2 nie będzie widział y2 == 1 i x2 == 0. W wątku 1 zapis x musi pojawić się przed nietrwałym zapisem do y, a w wątku 2 odczyt x musi występować po nietrwałym yodczycie . Więc jeśli wątek 2 widzi y2 == 1, musi również zobaczyć x2 == 1.

Należy jednak wziąć pod uwagę ten sam scenariusz co powyżej z określoną sekwencją, w której występują operacje:

Sequence Wątek 1 Wątek 2
1 x = 1; ...
2 Volatile.Write(ref y, 1); ...
3 ... int y2 = Volatile.Read(ref y);
4 ... int x2 = x;

Mimo że nietrwały zapis w y wątku 1 wystąpił przed nietrwałym odczytem y w wątku 2, wątek 2 może nadal widzieć y2 == 0wartość . y Nie gwarantuje, że na innym procesorze zostanie wyświetlona następująca liczba nietrwałych odczytów y na innym procesorze.

Note

  • Nietrwałe odczyty i zapisy zapewniają, że wartość jest odczytywana lub zapisywana w pamięci, a nie buforowana (na przykład w rejestrze procesora). W związku z tym można użyć tych operacji, aby zsynchronizować dostęp do pola, które można zaktualizować za pomocą innego wątku lub sprzętu.
  • Klasa Volatile udostępnia również operacje odczytu i zapisu dla niektórych typów 64-bitowych, takich jak Int64 i Double. Nietrwałe operacje odczytu i zapisu w takiej 64-bitowej pamięci są niepodzielne nawet w przypadku procesorów 32-bitowych, w przeciwieństwie do zwykłych operacji odczytu i zapisu.

Nietrwałe operacje pamięci są przeznaczone dla specjalnych przypadków synchronizacji, gdzie normalne blokowanie nie jest akceptowalną alternatywą. W normalnych okolicznościach instrukcja C# lock, instrukcja Visual Basic SyncLock, a klasa Monitor zapewnia najprostszy i najmniej podatny na błędy sposób synchronizowania dostępu do danych, a klasa Lazy<T> zapewnia prosty sposób pisania leniwego kodu inicjowania bez bezpośredniego używania podwójnej blokady.

Metody Volatile.Read i Volatile.Write umożliwiają korzystanie z funkcji, które nie są obsługiwane w językach. Przykład:

  • Niektóre języki, takie jak Visual Basic, nie rozpoznają koncepcji operacji nietrwałej pamięci. Klasa Volatile udostępnia te funkcje w takich językach.

    Note

    Wywołanie jednej z tych metod ma wpływ tylko na pojedynczy dostęp do pamięci. Aby zapewnić skuteczną synchronizację dla pola, cały dostęp do pola musi być używany i Volatile.ReadVolatile.Write.

  • W języku C# użycie volatile modyfikatora w polu gwarantuje, że każdy dostęp do tego pola jest operacją nietrwałej pamięci, ale volatile modyfikator nie może być stosowany do elementów tablicy. Metody Volatile.Read i Volatile.Write mogą być używane w elementach tablicy.

Metody

Nazwa Opis
Read(Boolean)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Byte)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Double)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Int16)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Int32)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Int64)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(IntPtr)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(SByte)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(Single)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(UInt16)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(UInt32)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(UInt64)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read(UIntPtr)

Odczytuje wartość określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Read<T>(T)

Odczytuje odwołanie do obiektu z określonego pola. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: jeśli operacja odczytu lub zapisu pojawi się po tej metodzie w kodzie, procesor nie może przenieść go przed tą metodą.

Write(Boolean, Boolean)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Byte, Byte)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Double, Double)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Int16, Int16)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Int32, Int32)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Int64, Int64)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(IntPtr, IntPtr)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(SByte, SByte)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(Single, Single)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(UInt16, UInt16)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(UInt32, UInt32)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(UInt64, UInt64)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write(UIntPtr, UIntPtr)

Zapisuje określoną wartość w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Write<T>(T, T)

Zapisuje określone odwołanie do określonego obiektu w określonym polu. W systemach, które tego wymagają, wstawia barierę pamięci, która uniemożliwia procesorowi zmienianie kolejności operacji pamięci w następujący sposób: Jeśli przed tą metodą w kodzie pojawi się odczyt lub zapis, procesor nie może przenieść go po tej metodzie.

Dotyczy

Zobacz też