Volatile Класс

Определение

Содержит методы для выполнения операций с переменной памятью.

public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
Наследование
Volatile

Комментарии

В многопроцессорной системе из-за оптимизации производительности в компиляторе или процессоре обычные операции памяти могут быть переупорядочены при работе с несколькими процессорами в одной памяти. Операции с переменной памятью препятствуют переупорядочению определенных типов в отношении операции. Переменная операция записи предотвращает переупорядочение предыдущих операций с памятью в потоке после переменной записи. Переменная операция чтения предотвращает переупорядочение последующих операций памяти в потоке до изменения порядка операций чтения. Эти операции могут включать барьеры памяти на некоторых процессорах, которые могут повлиять на производительность.

Например, рассмотрим следующий сценарий с двумя потоками и двумя Int32 полями x и y изначально равными нулю:

Поток 1 Поток 2
x = 1; int y2 = Volatile.Read(ref y);
Volatile.Write(ref y, 1); int x2 = x;

Изменяющееся чтение и запись предотвращает переупорядочение двух операций в каждом потоке, таких как компилятор или обработчик. Независимо от порядка, в котором эти операции на самом деле выполняются на одном потоке относительно другого потока, даже в многопроцессорной системе, где потоки могут выполняться на разных процессорах, переменные операции гарантируют, что поток 2 не будет видеть y2 == 1 и x2 == 0. На потоке 1 запись должна возникать до того, как переменная запись xyв , а на потоке 2 x чтение должно возникать после нестабильного yчтения. Таким образом, если поток 2 видит y2 == 1, он также должен видеть x2 == 1.

Однако рассмотрим тот же сценарий, что и выше, с определенной последовательностью, в которой выполняются операции:

Последовательность Поток 1 Поток 2
1 x = 1; ...
2 Volatile.Write(ref y, 1); ...
3 ... int y2 = Volatile.Read(ref y);
4 ... int x2 = x;

Несмотря на то, что переменная запись y в потоке 1 произошла до того, как в потоке 2 произошла переменная чтения y , поток 2 может по-прежнему видеть y2 == 0. Переменная запись, которая y не гарантирует, что следующее нестабильное чтение y на другом процессоре увидит обновленное значение.

Note

  • Переменные операции чтения и записи гарантируют, что значение считывается или записывается в память, а не кэшируется (например, в регистре процессора). Таким образом, эти операции можно использовать для синхронизации доступа к полю, которое можно обновить другим потоком или оборудованием.
  • Класс Volatile также предоставляет операции чтения и записи для некоторых 64-разрядных типов, таких как Int64 и Double. Переменные операции чтения и записи в такой 64-разрядной памяти атомарны даже на 32-разрядных процессорах, в отличие от обычных операций чтения и записи.

Операции с переменной памятью предназначены для особых случаев синхронизации, когда обычная блокировка не является приемлемой альтернативой. В обычных обстоятельствах оператор C# lock, оператор Visual Basic SyncLock и класс Monitor предоставляет самый простой и наименее подверженный ошибкам способ синхронизации доступа к данным, а класс Lazy<T> предоставляет простой способ записи отложенного кода инициализации без использования двойной проверки блокировки.

Volatile.Write Методы Volatile.Read обеспечивают функциональность, которая не поддерживается на языках. Рассмотрим пример.

  • Некоторые языки, такие как Visual Basic, не распознают концепцию переменных операций памяти. Класс Volatile предоставляет эту функциональность на таких языках.

    Note

    Вызов одного из этих методов влияет только на один доступ к памяти. Чтобы обеспечить эффективную синхронизацию для поля, все доступ к полю должен использоваться Volatile.Read и Volatile.Write.

  • В C#использование volatile модификатора в поле гарантирует, что каждый доступ к этому полю является переменной операцией памяти, но volatile модификатор не может применяться к элементам массива. Методы Volatile.Read и Volatile.Write методы можно использовать для элементов массива.

Методы

Имя Описание
Read(Boolean)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Byte)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Double)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Int16)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Int32)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Int64)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(IntPtr)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(SByte)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(Single)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(UInt16)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(UInt32)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(UInt64)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read(UIntPtr)

Считывает значение указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Read<T>(T)

Считывает ссылку на объект из указанного поля. В системах, требующих его, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если после этого метода в коде отображается чтение или запись, обработчик не может переместить его перед этим методом.

Write(Boolean, Boolean)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Byte, Byte)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Double, Double)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Int16, Int16)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Int32, Int32)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Int64, Int64)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(IntPtr, IntPtr)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(SByte, SByte)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(Single, Single)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(UInt16, UInt16)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(UInt32, UInt32)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(UInt64, UInt64)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write(UIntPtr, UIntPtr)

Записывает указанное значение в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Write<T>(T, T)

Записывает указанную ссылку на объект в указанное поле. В системах, которым требуется это, вставляет барьер памяти, который предотвращает переупорядочение операций памяти процессора следующим образом: если перед этим методом в коде отображается чтение или запись, обработчик не может переместить его после этого метода.

Применяется к

См. также раздел