time.sleep() Python 3.x 和 Windows 不准确 7

Inaccurate time.sleep() with Python 3.x and Windows 7

this post 开始,我在 Windows 下确定了 Python 的 time.sleep() 函数的非功能性实现7(企业版,64 位和 Python 3.4.4)。

这里是参考.py脚本:

import threading, time

def Return():
    return

def Setup():
    for _ in range(10):
        time_before = time.time()
        Return()
        wait_delay = -time.time()

        delays = []
        InputFrequency = 60

        while (time.time() - time_before) < (1 / InputFrequency):
            time.sleep(0)

        wait_delay += time.time()

        delays.append(wait_delay)

        print("Output frequency: " + str([1/t for t in delays][0]) + " Hz")

threading.Thread(target=Setup).start()

根据 this 示例,此脚本应产生大约 60Hz 的输出频率。然而,当 运行 在我的 Windows 7 Enterprise 机器上时,这些是我收到的给定输入频率的输出频率:

输入:10Hz - 输出:9.15Hz


输入:20Hz - 输出:16.03Hz


输入:30Hz - 输出 21.37Hz


输入范围:40Hz - 64Hz - 输出:32.05Hz


输入范围:65Hz - 10kHz+ - 输出:64.10Hz


这是怎么回事?为什么不同的输入频率(40Hz 以上)会产生相同的输出频率?为什么输入频率超过10000Hz,输出频率上限为64.10Hz?我不认为这是 ~60Hz 时的 time.sleep() 分辨率问题。提供给 ideone.com 脚本的相同输入频率值会产生预期的输出频率,因此它一定与我的计算机有关。

Python 很少保证这些调用的行为方式,尤其是跨平台的。这里有两件事可能会出错 - time.time() 的分辨率比您尝试达到的分辨率差,或者 sleep 的分辨率是。

在最近的平台上,睡眠应该大致准确至少 1 到 2 毫秒,如此处报道:

How accurate is python's time.sleep()?

剩下 time.time()。此特定调用的文档警告准确性可能很差:

Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

幸运的是,time.perf_counter() 中提供了更高分辨率的时钟 API,它尝试访问平台上可用的最高分辨率时钟。来自文档:

Return the value (in fractional seconds) of a performance counter, i.e. a clock with the highest available resolution to measure a short duration. It does include time elapsed during sleep and is system-wide. The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid.

在 Windows 的情况下,这似乎比解决您的问题的 60Hz 更好。