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