Почему этому образцу MSDN CompareExchange не требуется энергозависимое чтение?

Я искал поточно-ориентированную реализацию счетчика, использующую Interlocked , которая поддерживала увеличение на произвольные значения, и нашел этот образец прямо из Interlocked.Документация CompareExchange (немного изменена для простоты):

private int totalValue = 0;

public int AddToTotal(int addend)
{
    int initialValue, computedValue;
    do
    {
        // How can we get away with not using a volatile read of totalValue here?
        // Shouldn't we use CompareExchange(ref TotalValue, 0, 0)
        // or Thread.VolatileRead
        // or declare totalValue to be volatile?           
        initialValue = totalValue;

        computedValue = initialValue + addend;

    } while (initialValue != Interlocked.CompareExchange(
        ref totalValue, computedValue, initialValue));

    return computedValue;
}

 public int Total
 {
    // This looks *really* dodgy too, but isn't 
    // the target of my question.
    get { return totalValue; }
 }

Я понимаю, что пытается сделать этот код, но я не уверен, как это может сойти с рук, если не использовать изменчивое чтение общей переменной при назначении временная переменная, добавляемая в.

Есть ли шанс, что initialValue будет содержать устаревшее значение на протяжении всего цикла, из-за чего функция никогда не вернется? Или барьер памяти (?) В CompareExchange исключает такую ​​возможность? Любое понимание будет оценено.

РЕДАКТИРОВАТЬ : я должен пояснить, что я понимаю, что если CompareExchange вызвал последующее чтение totalValue , чтобы оно было актуальным по состоянию на последний вызов CompareExchange , тогда этот код подойдет. Но это гарантировано?

5
задан Ani 26 September 2011 в 15:06
поделиться