SpinWait in lockless update

 ̄綄美尐妖づ 提交于 2019-12-07 15:53:28

问题


While reading Albahari's Threading in C#, I've noticed that the "lock free update" pattern uses a SpinWait at the end of the cycle:

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();
    }
}

Note the spinWait.SpinOnce() call at the end. Is this call needed only to yield the thread in a single-threaded environment, or does it have an additional purpose?


回答1:


Short answer... Yes. The intent of SpinWait is to allow yielding the thread to the System so as not to starve processing due to SpinLock.

From 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.



来源:https://stackoverflow.com/questions/37799381/spinwait-in-lockless-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!