// IMPORTANT:
// Use this only for very short sleep intervals.
// One CPU core will run with 100% load during this interval.
public static void SleepPrecise(int s32_Interval) // in ms
{
if (s32_Interval <= 0)
return;
// System.Diagnostics.Stopwatch uses the performance counter in the processor
// which has a precision of micro seconds or even nano seconds.
Stopwatch i_Watch = new Stopwatch();
i_Watch.Start();
while (i_Watch.ElapsedMilliseconds < s32_Interval)
{
// SpinWait(80000) --> 1 ms on a 3.6 GHz AMD Radeon processor
Thread.SpinWait(5000);
}
}
5条答案
按热度按时间mwg9r5ms1#
它被用作非常短期的睡眠呼叫的替代品。
当您执行多线程锁定时,如果您试图获取的资源已经被锁定,您通常会进入睡眠状态并等待它变为空闲。当您这样做时,您给予了调度程序分配给您使用处理器的剩余时间,以便其他人可以尝试。通常情况下,这是很好的,特别是对于长时间的等待,比如等待IO,当您等待磁盘轴旋转时,其他进程的负载可以在CPU上运行。
然而,有时候,你在等待一小段时间。在这些情况下,你通常会给予你的剩余时间,无论如何,并等待所有其他线程做他们的事情之前,得到另一个去..所以你可以作弊,而不是等待,你坐在那里不断地轮询‘我们快到了吗?如果锁只占用你剩余时间的一小部分,这将成为一种非常有效的等待方式,它也非常有效,因为调度程序不必重新安排所有其他线程来使用你正常等待所给予的时间。
显然,如果你每次想要一个锁时都旋转,你不会很受欢迎,你的应用程序会变得缓慢,并使用100%的CPU,但在非常小的剂量下,在正确的时间,它使应用程序更响应。
如果你现在在想“我应该什么时候使用它?”',这是一个棘手的调用-如果你有一个资源,经常锁定和解锁非常快,然后自旋锁周围,而不是等待是一个好主意(然后测试你的应用程序的性能),如果你尝试旋转很短的时间,然后回落到正常的等待,这是一个合理的方式了。但一般来说,你永远不需要使用它。
bxpogfeg2#
目的是做一个“廉价”的等待,如果你相信你正在等待的条件会实现 * 非常,非常快 *。通常,如果你在等待什么,你让线程进入睡眠状态,处理器/操作系统将上下文切换到另一个线程。上下文切换并不是特别便宜,所以如果你对这种情况有深入的了解,并且相信等待比上下文切换便宜,你可以选择等待。
我的建议是:如果你需要问,你不需要使用它。(我自己从来没有想要过)基本上,这是在极少数情况下真正有用的东西之一,但大多数人应该远离它。
41zrol4v3#
顺便说一下,微软已经从Windows 7中摆脱了线程调度器自旋锁机制,因为它不能很好地扩展多核CPU。看看this:
编辑:由于Channel9不再(在我看来是愚蠢的决定),我发布的链接不再有效。您可以在YouTube上找到视频
r6vfmomb4#
就我而言(我很高兴更正!),自旋等待的唯一用途是在实现锁定或线程间回调机制时使用。而且两者都不应该手动完成(通常),因为它们已经存在。
当你锁定了一个资源,而另一个线程请求同步访问它时,它基本上必须等待第一个线程使用完它。这种等待可以通过简单地在循环中旋转来完成(或者如Jon所提到的睡眠+上下文切换)。
jc3wubiy5#
如果你需要一个精确的睡眠时间,你不能使用
Thread.Sleep()
,因为它非常不精确(± 25毫秒,取决于CPU负载),因为Windows是一个多任务操作系统。我使用下面的代码来计时相关的、只有几毫秒的短睡眠间隔。如果您需要极高的定时精度,您还可以: