无锁更新中的 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.
在阅读 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.