继this帖子后,我在Windows 7(Enterprise,64-bit和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企业版机器上运行时,这些是我在给定输入频率下收到的输出频率:
输入: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脚本的相同输入频率值会产生预期的输出频率,因此必须与我的计算机相关。
答案 0 :(得分:2)
Python几乎不保证这些调用的行为方式,特别是跨平台。这里有两件事可能会出错 - time.time()
的分辨率比你想要达到的分辨率或sleep
分辨率更差。
如下所述,在最近的平台上,睡眠应该至少准确1到2毫秒:
How accurate is python's time.sleep()?
这会留下time.time()
。此特定呼叫的文档警告准确性可能很差:
请注意,即使时间总是作为浮点返回 数字,并非所有系统都提供比1更精确的时间 第二。虽然此函数通常返回非递减值,但它 如果系统时钟有,则可以返回比先前调用更低的值 在这两个电话之间被搁置了。
幸运的是,time.perf_counter()
中提供了更高分辨率的时钟API,它试图访问平台上可用的最高分辨率时钟。来自文档:
返回性能计数器的值(以小数秒为单位), 即具有最高可用分辨率的时钟来测量短路 持续时间。它确实包括睡眠期间经过的时间 全系统。返回值的参考点未定义, 这样只有连续调用结果之间的差异 是有效的。
对于Windows,这似乎优于60Hz,可以纠正您的问题。