无锁更新中的 SpinWait

SpinWait in lockless update

在阅读 Albahari's Threading in C# 时,我注意到 "lock free update" 模式在循环结束时使用了 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() 调用。此调用是否只需要在单线程环境中产生线程,还是有其他目的?

简答...是的。 SpinWait 的目的是允许将线程交给系统,以免因 SpinLock.

而导致处理不足

来自 MSDN

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

SpinWait encapsulates common spinning logic. On single-processor machines, yields are always used instead of busy waits, and on computers with Intel processors employing Hyper-Threading technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of spinning and true yielding.

SpinWait is a value type, which means that low-level code can utilize SpinWait without fear of unnecessary allocation overheads. SpinWait is not generally useful for ordinary applications. In most cases, you should use the synchronization classes provided by the .NET Framework, such as Monitor. For most purposes where spin waiting is required, however, the SpinWait type should be preferred over the SpinWait method.