为什么Sleep(1)的睡眠时间在Windows中似乎是可变的?

时间:2010-10-25 21:41:58

标签: windows sleep

上周我需要测试一些不同的算法函数并让自己很容易,我添加了一些人工睡眠并简单地测量了时钟时间。像这样:

start = clock();
for (int i=0;i<10000;++i)
   {
   ...
   Sleep(1);
   ...
   }
end = clock();

由于睡眠的参数以毫秒表示,我预计总挂钟时间大约为10秒(由于算法而大得多,但现在并不重要),这确实是我的结果。

今天早上我因为新的Microsoft Windows热修复而不得不重启我的电脑,令我惊讶的是Sleep(1)不再需要1毫秒,但大约需要0.0156秒。

所以我的测试结果完全搞砸了,因为总时间从10秒增加到大约156秒。

我们在几台PC上进行了测试,显然在一些PC上,一次睡眠的结果确实是1 ms。在其他PC上它是0.0156秒。

然后,突然间,一段时间后,睡眠时间下降到0.01秒,然后一小时后又回到0.001秒(1毫秒)。

这是Windows中的正常行为吗? Windows重启后的第一个小时是“困”,然后在一段时间后逐渐获得更高的睡眠粒度? 或者是否还有其他方面可以解释行为的变化?

在我的所有测试中,没有其他应用程序同时运行(或者:至少没有运行任何CPU)。

有什么想法吗?

操作系统是Windows 7。

6 个答案:

答案 0 :(得分:6)

我没有听说过解决方案本身就是这样,但一般来说,睡眠的分辨率遵循任务调度程序的时钟滴答。因此默认情况下,通常为10或15毫秒,具体取决于Windows的版本。您可以通过发出timeBeginPeriod手动将其设置为1毫秒。

答案 1 :(得分:2)

我猜这是调度程序。每个操作系统都有一定的粒度。如果你要求它做一些比这更低的事情,结果并不完美。通过要求睡眠1毫秒(特别是经常),调度员可能会认为你不重要,让你睡得更久,或者你的睡眠可能会在时间片结束时出现。

睡眠电话是一个咨询电话。它告诉操作系统你要睡觉的时间X.它可以小于X(由于信号或其他东西),或者它可以更多(正如你所看到的)。

另一个Stack Overflow问题有way to do it,但您必须使用winsock。

答案 2 :(得分:1)

当您呼叫睡眠时,处理器正在停止该线程,直到它可以在&gt; =恢复到被叫睡眠时间时恢复。有时由于线程优先级(在某些情况下会导致Sleep(0)导致程序无限期挂起),程序可能会在以后恢复,因为为另一个线程分配了更多的处理器周期来执行工作(主要是OS线程具有更高的优先级) )。

答案 3 :(得分:1)

我刚刚在线程Sleep Less Than One Millisecond中写了一些关于sleep()函数的文字。 sleep()函数的特性取决于底层硬件和多媒体计时器接口的设置。

Windows更新可能会改变行为,即Windows 7与Vista相比会对待不同的内容。查看我在该主题及其链接中的评论,以了解更多信息与sleep()函数的关系。

答案 4 :(得分:0)

睡眠定时器很可能没有足够的分辨率。

timeGetDevCaps 函数文档中所述,当您调用Sleep函数时会得到什么样的解析?

答案 5 :(得分:0)

Windows睡眠粒度通常为16毫秒,除非您或其他程序对此进行更改,否则您将获得此粒度。当你在其他日子获得1ms粒度和其他16ms时,其他一些程序可能会设置时间片(对你的程序也有影响)。我认为我的Labview就是这样做的。