InterlockedExchange и видимость памяти

Я прочитал статью Проблемы синхронизации и многопроцессорности , и у меня есть вопрос о InterlockedCompareExchange и InterlockedExchange. Речь идет собственно о последнем примере в статье.У них есть две переменные iValue и fValueHasBeenComputed , и в CacheComputedValue () они изменяют каждую из них, используя InterlockedExchange :

InterlockedExchange ((LONG*)&iValue, (LONG)ComputeValue());  // don't understand
InterlockedExchange ((LONG*)&fValueHasBeenComputed, TRUE); // understand

Я понимаю, что Я могу использовать InterlockedExchange для изменения iValue , но достаточно ли этого просто сделать

iValue = ComputeValue();

Так действительно ли необходимо использовать InterlockedExchange для установки iValue? Или другие потоки будут правильно видеть iValue, даже если iValue = ComputeValue (); . Я имею в виду, что другие потоки будут правильно видеть iValue, потому что после него идет InterlockedExchange .

Существует также статья Принципиальная модель последовательной памяти для платформ Microsoft Native Code . Есть пример 3.1.1 с более или менее таким же кодом. Одна из рекомендаций Сделайте y заблокированным . Обратите внимание - не одновременно y и x .

Обновление
Просто чтобы прояснить вопрос. Дело в том, что я вижу противоречие. В примере из «Проблемы синхронизации и многопроцессорности» используются два InterlockedExchange . Напротив, в примере 3.1.1 «Базовое переупорядочение» (который, я думаю, очень похож на первый пример) Херб Саттер дает эту рекомендацию

«Сделайте y блокированным: если y блокируется, то гонки на y , потому что он обновляется атомарно, и нет гонки по x, потому что a -> b -> d. "

.В этом проекте Herb не использует две взаимосвязанные переменные (если я прав, он имеет в виду использование InterlockedExchange только для y ).

8
задан Sergei Kurenkov 8 October 2011 в 07:57
поделиться