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

问题描述 投票:2回答:6

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

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

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

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

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

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

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

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

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

有任何想法吗?

无论哪种方式7。

windows sleep
6个回答
6
投票

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


2
投票

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

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

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


1
投票

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


1
投票

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

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


0
投票

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

当您按照timeGetDevCaps 函数文档中的说明调用Sleep函数时,您会得到什么样的分辨率?


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.