Какова цель ключевого слова volatile в C # - PullRequest
17 голосов
/ 05 ноября 2010

Для чего нужно ключевое слово volatile в C #?

Где мне нужно использовать это ключевое слово?

Я видел следующее утверждение, но не могу понять, почему volatile требуется здесь?

internal volatile string UserName; 

Ответы [ 6 ]

28 голосов
/ 05 ноября 2010

Я отсылаю вас к разделу 10.5.3 спецификации, в котором говорится:

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

A чтение изменчивого поля называется изменчивое чтение. Изменчивое чтение имеет «Овладеть семантикой»; то есть гарантированно произойдет до любого ссылки на память, которые происходят после это в последовательности команд.

A запись изменчивого поля называется изменчивая запись. Летучая запись имеет «Семантика релиза»; то есть гарантированно произойдет после любой памяти ссылки до написания инструкция в инструкции последовательность.

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

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

7 голосов
/ 05 ноября 2010

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

Примером чего-то, что было бы энергозависимым, был бы аппаратный регистр, в котором ваш код отображал память и считывал, чтобы определить, когда установлен флаг. Аппаратное обеспечение может установить значение во время работы вашего кода, и без использования ключевого слова volatile вы не заметите это изменение, поскольку сборка фактически никогда не проверит это значение.

6 голосов
/ 05 ноября 2010

Volatile - подсказка для компилятора (и компилятора ngen / jit), что значение этой переменной может измениться в любой момент, и, таким образом, будет отключена оптимизация доступа к переменной путем кэширования значения локально volatile.

Рассмотрим следующий код:

If (UserName == "")
    // do something
If (UserName == "Fred")
    // do something

Если volatile отсутствует, компилятор может сгенерировать IL, где он сохраняет ссылку в стеке для первого сравнения, а затем повторно использует ее для второго сравнения. Однако добавление volatile сообщает компилятору, что ссылка может быть изменена другим потоком, что вынуждает его генерировать IL, который не будет повторно использовать стековую копию из первого сравнения.

4 голосов
/ 05 ноября 2010

MSDN будет суммировать лучше, чем я ....

"Ключевое слово volatile указывает, что поле может быть изменено несколькими потоками, которые выполняются одновременно. Поля, которые объявлены как volatile, не подлежат оптимизации компилятора, предполагающей доступ к одному потоку. Это гарантирует, что большинство текущее значение постоянно присутствует в поле. "

http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

3 голосов
/ 05 ноября 2010

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

http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx

2 голосов
/ 05 ноября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...