【问题标题】:Inaccurate time.sleep() with Python 3.x and Windows 7Python 3.x 和 Windows 7 的 time.sleep() 不准确
【发布时间】:2017-10-02 01:08:24
【问题描述】:

继this 的帖子之后,我发现了在 Windows 7(企业版、64 位和 Python 3.4.4)下 Python 的 time.sleep() 函数的非功能性实现。

这是参考 .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 以上)会产生相同的输出频率?为什么即使输入频率超过10,000Hz,输出频率上限也是64.10Hz?我不相信这是 ~60Hz 的 time.sleep() 分辨率问题。提供给 ideone.com 脚本的相同输入频率值会产生预期的输出频率,因此它必须与我的计算机相关。

【问题讨论】:

  • 你检查过当前版本的python是否有什么不同吗?
  • 我没有,但我刚刚检查了我的 Python 2.7.12 安装,它给出了相同的错误输出频率。
  • 对,但是您的基线是 python 3,所以看来 python 3.6 可能是一个开始的地方。
  • 我刚刚使用 Python 3.6.0 安装并尝试了该文件,并且遇到了相同的错误输出频率。
  • 四处逛逛,我看到其他关于相对现代的 python 和操作系统的答案,睡眠大约是毫秒准确的,给予或接受。您是否考虑过选择某种数量的量来代替 sleep(0)?

标签: python python-3.x time sleep


【解决方案1】:

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

在最近的平台上,睡眠应该大约至少准确 1 到 2 毫秒,如下所述:

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

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

请注意,即使时间总是以浮点形式返回 数字,并非所有系统都提供比 1 更精确的时间 第二。虽然此函数通常返回非递减值,但它 如果系统时钟有 在两次通话之间被推迟。

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

返回性能计数器的值(以秒为单位), 即具有最高可用分辨率的时钟来测量短路 期间。它确实包括睡眠期间经过的时间,并且是 全系统。返回值的参考点未定义, 这样只有连续调用的结果之间的差异 有效。

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

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 2015-07-16
    • 2010-11-11
    • 1970-01-01
    • 2021-04-25
    • 2013-07-04
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多