Вопреки распространенному заблуждению, семантика получения / выпуска не гарантирует получение нового значения из общей памяти, они влияют только на порядок других операций с памятью вокруг операции с семантикой получения / выпуска. Каждый доступ к памяти должен быть, по крайней мере, таким же недавним, как и последнее чтение при получении, и не более устаревшим, чем запись следующего выпуска. (Аналогично для барьеров памяти.)
В этом коде у вас есть только одна общая переменная для беспокойства: totalValue
. Тот факт, что CompareExchange является атомарной операцией RMW, достаточен для того, чтобы переменная, с которой он работает, обновлялась. Это связано с тем, что атомарные операции RMW должны гарантировать, что все процессоры согласуются с тем, что является самым последним значением переменной.
Относительно другого Total
свойства, которое вы упомянули, будет ли оно правильным или нет, зависит от того, что от него требуется. Некоторые моменты:
* * 1010
int
гарантированно является атомарным, поэтому вы всегда получите действительное значение (в этом смысле код, который вы показали, можно было бы считать «правильным», если бы ничего, кроме
некоторого действительного) возможно, требуется устаревшее значение)
если чтение без семантики получения (
Volatile.Read
или чтение
volatile int
) означает, что все операции с памятью, записанные после того, как это может действительно произойти раньше (операции чтения со старыми значениями и записи становятся видимыми для других процессоров, прежде чем они должны это сделать)
если для чтения не используется атомарная операция RMW (например,
Interlocked.CompareExchange(ref x, 0, 0)
), полученное значение может не соответствовать тому, что некоторые другие процессоры видят как самое последнее значение
если требуется как самое свежее значение, так и порядок в отношении других операций с памятью,
Interlocked.CompareExchange
должен работать (базовый WinAPI
InterlockedCompareExchange
использует полный барьер, не очень уверен в C # или .Net спецификации), но если вы хотите быть уверены, вы можете добавить явный барьер памяти после чтения