Поделиться через


Volatile Класс

Определение

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

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

Комментарии

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

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

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

Переменные операции чтения и записи препятствуют переупорядочению двух операций в каждом потоке, например компилятором или процессором. Независимо от того, в каком порядке эти операции выполняются в одном потоке относительно другого потока, даже в многопроцессорной системе, где потоки могут выполняться на разных процессорах, переменные операции гарантируют, что поток 2 не будет видеть y2 == 1 и x2 == 0. В потоке 1 операция записи x в должна отображаться перед переменчивой записью в y, а в потоке 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;

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

Примечание

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

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

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

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

    Примечание

    Вызов одного из этих методов влияет только на один доступ к памяти. Чтобы обеспечить эффективную синхронизацию для поля, весь доступ к полю должен использовать 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)

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

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

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