操作系统:Windows 7
当将WinAPI Sleep()函数调用为Sleep(1)时,线程实际上会休眠15ms。我在循环中做了100次,总睡眠时间是1500毫秒而不是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;
}
EDIT2:似乎有些人获得1ms的原因是某些其他程序正在运行,它将系统范围的计时器分辨率设置为1ms。默认情况下,Windows 7上的此值应为15.6毫秒。
答案 0 :(得分:12)
Sleep
可以导致线程休眠的时间超过指定的超时时间,它只能保证线程至少会在这段时间内休眠。
休眠间隔过后,线程就可以运行了。如果指定0毫秒,则线程将放弃其时间片的剩余部分但仍保持准备状态。 请注意,不保证立即运行就绪线程。因此,线程可能在睡眠间隔过去一段时间后才会运行。有关详细信息,请参阅Scheduling Priorities。
答案 1 :(得分:9)
这是常见的行为
是。
Window的线程调度程序适用于时间量程(确切长度取决于各种因素,包括Windows版本和版本)。实际上,任何非零延迟都会四舍五入到完整的量子。
答案 2 :(得分:2)
我在Windows上发现有关时间安排的最佳文章是here和here。有用的部分是,一旦您更改多媒体计时器分辨率(例如timeBeginPeriod(1) 1ms),它也会影响睡眠命令,因为它通常会影响调度程序。 这就是说,在非实时操作系统上实现1ms的准确性是不可行的。
答案 3 :(得分:1)
您应该检查机器的计时器分辨率。有关详细信息,请参阅msdn documentation of Sleep()。
答案 4 :(得分:1)
这是非常正常的行为,因为大多数时钟分辨率大约为10-15 ms。因此,如果使用小于时钟分辨率的值(在您的情况下为1)调用它,则可能必须至少等待一个时钟周期,这就是它睡眠时间超过您想要的时间。
通常,由于这些问题,您不应将睡眠用于需要此类精确度的事物。
答案 5 :(得分:1)
行为没问题。底层硬件,操作系统版本,甚至运行软件都会受到影响 OS关于sleep()函数的习惯。
如果在dwMilliseconds小于系统中断周期的情况下调用sleep,则调用将在下一个中断时返回。这样,实际延迟取决于调用睡眠的时间(相对于中断周期)。
当需要睡眠(1)时,建议使用多媒体定时器接口将中断频率增加到硬件支持的最大值。
有关sleep()函数,等待计时器功能,计时器分辨率和多媒体计时器设置的详细概述,请参阅Windows Timestamp Project
答案 6 :(得分:0)
(调试或发布版本?)
你是如何衡量延迟的?你使用的是精确的方法吗? (QueryPerformanceCounter的)
我认为您不应该依赖Windows操作系统来获得准确的计时;它不是一个实时操作系统,并且会有外部“力量”从你的过程中窃取时间。