Я знаю, что модель памяти .NET(на .NET Framework, а не compact/micro/silverlight/mono/xna/what-have-you) гарантировала, что для определенных типов (в первую очередь примитивных целых и справочных) операций были гарантированный атомный.
Кроме того, я считаю, что команда test-and-set x86/x64 (и Interlocked.CompareExchange
) фактически ссылается на местоположение глобальной памяти, поэтому, если ей удастся, другой Interlocked.CompareExchange
увидит новое значение.
Наконец, я считаю, что ключевое слово volatile
- это инструкция для компилятора для распространения чтения и записи ASAP и не изменять порядок операций с этой переменной (правильно?).
Это приводит к нескольким вопросам:
- Я верю ли мои убеждения?
-
Interlocked.Read
не имеет перегрузки для int, только для longs (которые являются 2 WORD и, следовательно, обычно не читаются атомарно). Я всегда предполагал, что модель памяти .NET гарантирует, что самое новое значение будет видно при чтении int/ссылок, однако с кэшами процессора, регистрами и т.д. Я начинаю видеть, что это может быть невозможно. Итак, есть способ принудительно переназначить переменную? - Неустойчиво ли достаточно для решения вышеуказанной проблемы для целых чисел и ссылок?
- В x86/x64 я могу предположить, что...
Если есть две глобальные целочисленные переменные x и y, обе инициализируются до 0, если я пишу:
x = 1;
y = 2;
Этот поток NO будет видеть x = 0 и y = 2 (т.е. записи будут происходить по порядку). Изменяется ли это, если они нестабильны?