SpinLock并没有真正做繁忙循环等待吗?



>我有以下代码

class Program
{
static SpinLock sl = new SpinLock();
public static void Foo(object arg)
{
bool r = false;
sl.Enter(ref r);
}
public static void Main(string[] args)
{
bool r = false;
sl.Enter(ref r);
ThreadPool.QueueUserWorkItem(Foo);
Thread.Sleep(5000);
sl.Exit();
Thread.Sleep(5000);
}
}

当我执行它时,我在整个程序运行中看到 ~0% 的 CPU 负载。我原本以为会看到一些CPU由于在sl.Enter()调用内旋转而烧毁,但事实并非如此。

根据SpinLock的消息来源,它在引擎盖下使用SpinWait,这反过来又在某个时候调用Thread.Sleep(1)

这是否意味着SpinLockSpinWait都不是真正的"微调器",而是仍然求助于操作系统调度程序来产生一些 CPU 份额?

编辑

这个问题可以按以下方式重新表述:

使用繁忙循环可确保一个线程释放锁和另一个线程获取锁之间的时间最短。在这方面我可以依靠SpinLock/SpinWait吗?据我所知,答案是否定的,因为它确实Sleep至少 1 微秒,并且在此期间锁可能会在某个地方释放。

关于您编辑的问题,是的,繁忙的旋转将为您提供线程之间通信的最低延迟,但您将通过消耗 CPU 时间来支付费用。

另一方面,您可以使用不那么激进的SpinWait,或者您可以在两者之间编写一些代码,例如这样。

这归结为您重视延迟的程度以及您必须保留多少内核进行权衡。

最新更新