В соответствии с этой онлайн-книгой ключевое слово volatile
в С# не защищает от переупорядочения операций записи, за которыми следуют операции чтения. Он дает этот пример, в котором оба a
и b
могут быть установлены на 0
, несмотря на то, что x
и y
являются volatile
:
class IfYouThinkYouUnderstandVolatile
{
volatile int x, y;
void Test1() // Executed on one thread
{
x = 1; // Volatile write (release-fence)
int a = y; // Volatile read (acquire-fence)
...
}
void Test2() // Executed on another thread
{
y = 1; // Volatile write (release-fence)
int b = x; // Volatile read (acquire-fence)
...
}
}
Это похоже на то, что в спецификации указано в 10.5.3:
Чтение изменчивого поля называется изменчивым чтением. Неустойчивое чтение имеет "приобретать семантику"; то есть он гарантированно будет происходить до любых ссылок на память, которые происходят после него в последовательности команд.
Запись изменчивого поля называется volatile write. У изменчивой записи есть "семантика выпуска"; то есть это гарантировано произойдет после любых ссылок на память до команды записи в последовательности команд.
В чем причина этого? Есть ли прецедент, в котором мы не против перезаписывания операций Write-Read?