for (;;) {
// берём начальное значение общей переменной,
// которую мы собираемся изменять
oldValue = sharedVariable;
... берём начальные значения других параметров ...
newValue = ... вычисляем новое значение, используя
oldValue и копии остальных параметров ...
// вместо Xxx может быть Acquire, Release, или ничего
if (InterlockedCompareExchangeXxx(
&sharedVariable,
newValue, oldValue) == oldValue) {
break; // запись удалась
}
... удаляем newValue ...
} // попытаемся снова
Мы вычисляем новое значение, и затем вызовом
InterlockedCompareExchange записываем его в общую переменную только в том случае, если её значение не изменялось. Если оно изменилось, значит другой поток нас опередил; в этом случае попытаемся выполнить операцию по-новой, с самого начала, — в надежде, что в следующий раз никто нас не «подрежет».