Threading.SpinWait 结构与 Thread.SpinWait 方法
Posted
技术标签:
【中文标题】Threading.SpinWait 结构与 Thread.SpinWait 方法【英文标题】:Threading.SpinWait struct vs Thread.SpinWait method 【发布时间】:2021-12-23 18:25:33 【问题描述】:我想知道Threading.Thread.SpinWait
方法和Threading.SpinWait
结构之间是否有任何区别。
特别是,在应用程序中实现 spinwait 的惯用方式是什么:
Thread.SpinWait(1);
或
SpinWait spinWait = new SpinWait();
// ...
spinWait.SpinOnce();
【问题讨论】:
【参考方案1】:原来 SpinWait 结构的documentation 建议不要直接使用Thread.SpinWait()
方法。正确的做法是:
SpinWait spinWait = new SpinWait();
// ...
spinWait.SpinOnce();
SpinWait 封装了常见的旋转逻辑。在单处理器机器上,总是使用产量而不是忙等待,而在采用超线程技术的英特尔处理器的计算机上,它有助于防止硬件线程不足。 SpinWait 封装了纺丝和真产量的良好组合。
SpinWait 是一种值类型,这意味着低级代码可以利用 SpinWait 而不必担心不必要的分配开销。 SpinWait 通常不适用于普通应用程序。在大多数情况下,您应该使用 .NET Framework 提供的同步类,例如 Monitor。 但是,对于需要旋转等待的大多数用途,应该首选 SpinWait 类型而不是 Thread.SpinWait 方法。
http://www.albahari.com/threading/part5.aspx#_SpinLock_and_SpinWait 补充了一些细节:
在其当前实现中,SpinWait 在屈服之前执行 CPU 密集型旋转 10 次迭代。但是,它不会在每个循环之后立即返回给调用者:相反,它调用
Thread.SpinWait
通过 CLR(最终是操作系统)在设定的时间段内旋转。这个时间段最初是几十纳秒,但每次迭代都会加倍,直到 10 次迭代结束。这确保了 CPU 密集型旋转阶段所花费的总时间具有一定的可预测性,CLR 和操作系统可以根据条件对其进行调整。通常,它在几十微秒的范围内——很小,但比上下文切换的成本要高。在单核机器上,SpinWait 每次迭代都会产生。您可以通过属性 NextSpinWillYield 测试 SpinWait 是否会在下一次旋转时让步。如果 SpinWait 保持“spin-yielding”模式足够长的时间(可能 20 个周期),它将定期休眠几毫秒以进一步节省资源并帮助其他线程继续运行。
简而言之,据我了解,Threading.Thread.SpinWait
负责实际旋转,Threading.SpinWait
将其封装起来,使其在几乎所有情况下都能正常工作。
【讨论】:
以上是关于Threading.SpinWait 结构与 Thread.SpinWait 方法的主要内容,如果未能解决你的问题,请参考以下文章