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 方法的主要内容,如果未能解决你的问题,请参考以下文章

10th.U-boot——代码结构分析

数据结构与算法随笔:LeetCode算法练习

html中th与thead的详细区别

10th week task -2 Object 的起源

6th.关于中断结构系统

Thymeleaf th:text - 放置文本而不删除 HTML 结构