SpinWait в обновлении без блокировки

Читая Потоки Албахари в C#, я заметил, что шаблон "Блокировка бесплатного обновления" использует SpinWait в конце цикла:

static void LockFreeUpdate<T> (ref T field, Func <T, T> updateFunction)
  where T : class
{
    var spinWait = new SpinWait();
    while (true)
    {
        // read
        T snapshot1 = field;

        // apply transformation
        T calc = updateFunction (snapshot1);

        // compare if not preempted
        T snapshot2 = Interlocked.CompareExchange (ref field, calc, snapshot1);

        // if succeeded, we're done
        if (snapshot1 == snapshot2) return;

        // otherwise spin
        spinWait.SpinOnce();
    }
}

Обратите внимание spinWait.SpinOnce() позвоните в конце. Нужен ли этот вызов только для того, чтобы получить поток в однопоточной среде, или он имеет дополнительную цель?

1 ответ

Решение

Краткий ответ... Да. Намерение SpinWait разрешить передачу потока в систему, чтобы избежать потери ресурсов из-за SpinLock,

Из MSDN

https://msdn.microsoft.com/en-us/library/system.threading.spinwait(v=vs.110).aspx

SpinWait инкапсулирует обычную логику вращения. На однопроцессорных компьютерах выходы всегда используются вместо ожиданий, а на компьютерах с процессорами Intel, использующими технологию Hyper-Threading, это помогает предотвратить истощение аппаратных потоков. SpinWait заключает в себе хорошую смесь прядения и настоящей урожайности.

SpinWait является типом значения, что означает, что низкоуровневый код может использовать SpinWait, не опасаясь ненужных накладных расходов. SpinWait обычно не полезен для обычных приложений. В большинстве случаев вам следует использовать классы синхронизации, предоставляемые.NET Framework, например Monitor. Однако для большинства целей, где требуется ожидание вращения, тип SpinWait должен быть предпочтительнее метода SpinWait.

Другие вопросы по тегам