WinAPI Sleep()函数调用的睡眠时间比预期的要长



OS:Windows 7

当调用WinAPI Sleep()函数作为Sleep时(1),线程实际上会休眠15毫秒。我循环做了100次,总睡眠时间是1500米,而不是100米。

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

编辑:如果可能的话,你可以运行这个代码并公布睡眠时间有多长。我让我的一个朋友做了这个,他实际上在1毫秒时就完成了。

#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。

这种常见行为是吗

是的。

Window的线程调度程序在时间范围内工作(确切的长度取决于各种因素,包括Windows版本和版本)。实际上,任何非零延迟都被四舍五入为一个完整的量子。

Sleep会导致线程睡眠时间超过指定的超时时间,它只能保证线程至少睡眠该长度的时间。

来自文件:

经过睡眠间隔后,线程就可以运行了。如果指定0毫秒,线程将放弃剩余的时间片,但仍保持准备状态请注意,就绪线程不能保证立即运行。因此,线程可能直到经过睡眠间隔之后的某个时间才运行有关详细信息,请参阅安排优先级。

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

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

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

一般来说,由于这些问题,你不应该使用睡眠来处理需要如此精确的事情。

行为正常。底层硬件、操作系统版本,甚至正在运行的软件都在影响操作系统关于sleep()函数的习惯。

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

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

有关sleep()函数、可等待计时器函数、计时器分辨率和多媒体计时器设置的详细概述,请参阅Windows时间戳项目

(调试还是发布构建?)

你是如何衡量延迟的?你用的是精确的方法吗?(查询性能计数器)

我认为你不应该依赖Windows操作系统来获得准确的时间;它不是一个实时操作系统,会有外部"力量"从您的进程中窃取时间。

应为。最近我还在调试一个与此相关的问题。如果我用1毫秒调用睡眠,它将睡眠15毫秒。假设实际睡眠时间总是四舍五入到15毫秒的倍数是有道理的。

最新更新