Python 3.x 和 Windows 7 的 time.sleep() 不准确 [英] Inaccurate time.sleep() with Python 3.x and Windows 7

查看:43
本文介绍了Python 3.x 和 Windows 7 的 time.sleep() 不准确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

this 帖子中,我已经确定了 Windows 7(企业版、64 位和 Python 3.4.4)下 Python 的 time.sleep() 函数的非功能性实现.

Following on from this post, I've identified a non-functional implementation of Python's time.sleep() function under Windows 7 (Enterprise, 64-bit and Python 3.4.4).

这是参考 .py 脚本:

Here's the reference .py script:

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 机器上运行时,这些是我收到的给定输入频率的输出频率:

As per this example, this script should produce output frequencies of roughly 60Hz. However, when run on my Windows 7 Enterprise machine, these are the outputs frequencies I receive for a given input frequency:

输入:10Hz - 输出:9.15Hz

Input: 10Hz - Output: 9.15Hz

输入:20Hz - 输出:16.03Hz

Input: 20Hz - Output: 16.03Hz

输入:30Hz - 输出 21.37Hz

Input: 30Hz - Output 21.37Hz

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

Input Range: 40Hz - 64Hz - Output: 32.05Hz

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

Input Range: 65Hz - 10kHz+ - Output: 64.10Hz

这里发生了什么?为什么不同的输入频率(40Hz 以上)会产生相同的输出频率?为什么即使输入频率超过10,000Hz,输出频率上限仍为64.10Hz?我不认为这是 ~60Hz 的 time.sleep() 分辨率问题.提供给 ideone.com 脚本的相同输入频率值会产生预期的输出频率,因此它必须与我的计算机有关.

What is going on here? Why are varying input frequencies (above 40Hz) producing the same output frequency? Why is the output frequency upper limit 64.10Hz, even when the input frequency is over 10,000Hz? I don't believe it's a time.sleep() resolution issue at ~60Hz. The same input frequency values supplied to the ideone.com script produce the expected output frequencies, so it must be related to my computer.

推荐答案

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

Python makes very few guarantees about how these calls will behave, especially cross-platform. There are two things that can potentially go wrong here - time.time()'s resolution is worse than the resolution you're trying to achieve or sleep's resolution is.

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

Sleep should be roughly at least 1 to 2 ms accurate on recent platforms as reported here:

python 的 time.sleep() 有多准确?

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

This leaves time.time(). The documentation for this particular call warns the accuracy may be poor:

请注意,即使时间总是作为浮点数返回数字,并非所有系统都提供比 1 更好的时间精度第二.虽然此函数通常返回非递减值,但它如果系统时钟有,则可以返回比先前调用更低的值在两次通话之间受阻.

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,它尝试访问平台上可用的最高分辨率时钟.来自文档:

Fortunately, a higher resolution clock API is provided in time.perf_counter() which attempts to access the highest resolution clock available on platform. From the documentation:

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

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 更好,可以解决您的问题.

In the case of Windows, this seems to be better than 60Hz which corrects your problem.

这篇关于Python 3.x 和 Windows 7 的 time.sleep() 不准确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆