WinAPI睡眠()函数调用睡眠时间比预期更长

操作系统:Windows 7

当将WinAPI Sleep()函数调用为Sleep(1)时,该线程实际上会hibernate15ms。 我做了100次循环,总睡眠时间是1500ms而不是100次。

这是常见的行为,还是应该关心我的MOBO,CPU,Windows安装有问题?

编辑:如果可能的话,你可以运行这个代码,并发表多久的睡眠时间。 我让我的一个朋友运行这个,他实际上已经在1ms。

#include <iostream> #include <ctime> #include <Windows.h> void test(void) { std::cout << "Testing 1ms sleep." << std::endl; for (unsigned int i = 0; i < 10; i++) { std::clock_t startClocks = std::clock(); Sleep(1); std::clock_t clocksTaken = std::clock() - startClocks; std::cout << "Time: " << clocksTaken << "ms." << std::endl; } } int main(void) { test(); std::cin.sync(); std::cin.get(); return 0; } 

编辑2:似乎有些人得到1ms的原因是其他程序正在运行,将系统范围的定时器分辨率设置为1ms。 默认情况下,这应该在Windows 7上15.6ms。

这是常见的行为

它是。

窗口的线程调度程序工作在一个时间段(确切长度取决于各种因素,包括Windows版本和版本)。 有效地,任何非零延迟都会被舍入到一个完整的量子。

睡眠可以导致线程睡眠时间超过指定的超时时间,它只能保证线程至少睡眠这段时间。

从文档 :

休眠间隔过后,线程就可以运行了。 如果指定0毫秒,则线程将放弃其时间片的其余部分,但保持就绪状态。 请注意,现成的线程不能保证立即运行。 因此,直到休眠间隔过去一段时间之后,线程才可能运行。 有关更多信息,请参阅计划优先级 。

我发现在Windows上的时间最好的文章是在这里和这里 。 有用的部分是,一旦你改变多媒体计时器的分辨率(例如timeBeginPeriod(1) 1ms),它也会影响睡眠命令,因为它一般影响调度器。 这就是说,在非实时操作系统上实现1ms精度是不可行的。

你应该检查你的机器的定时器分辨率。 有关详细信息,请参阅Sleep()的msdn文档 。

这是非常正常的行为,因为大多数时钟分辨率都在10-15毫秒左右。 因此,如果你使用一个小于时钟分辨率的值(在你的情况下是1)来调用它,它可能将不得不等待一个时钟周期,这就是为什么它会比你想要的更长的睡眠时间。

一般来说,由于这些问题,您不应该将Sleep用于需要如此精确的事情。

行为是好的。 底层的硬件,操作系统的版本,甚至是运行软件都会影响操作系统在睡眠()功能方面的习惯。

如果以小于系统中断周期的dwMilliseconds调用睡眠,则调用将在下一个中断时返回。 这样,实际的延迟取决于睡眠的时间(相对于中断周期)。

当需要睡眠(1)时,建议使用多媒体定时器接口来增加硬件支持的最大中断频率。

有关睡眠()功能,等待定时器功能,定时器分辨率和多媒体定时器设置的详细概述可以在Windows时间戳项目

(调试或发布构建?)

你怎么测量延迟? 你用的是精确的方法吗? (QueryPerformanceCounter的)

我不认为你应该依靠Windows操作系统准确的时间; 它不是一个实时的操作系统,会有外部的“力量”从你的过程中偷走时间。