time.monotonic_ns 和 time.sleep 的奇怪交互

问题描述 投票:0回答:1

我注意到当

time.monotonic_ns
time.sleep
在很短的时间内相互作用时,会出现一些奇怪的行为。

为了调查这一点,我编写了以下“测试”。

import time

def main():
    while True:
        start = time.monotonic_ns()
        time.sleep(0.01)  # 10 milliseconds
        end = time.monotonic_ns()
        diff = end - start
        print("diff: {}".format(diff))

if __name__ == "__main__":
    main()

此代码大多数情况下会打印大约

15000000
(实际上正好是 15000000 ns 或 16000000 ns)或
15
毫秒的值,但有时只是
0
。 如果我进一步减少睡眠时间,它会具有完全相同的行为(即 15 毫秒或 0 纳秒)。

当我使用

time.time_ns
时,它每次都会非零(也更加随机,有时甚至会下降到 ~11 毫秒),
time.perf_counter_ns
也可以正常工作。我知道
time.process_time
将始终为 0,因为它不计算睡眠时间。
timeit.timit
还显示我的系统上的最小睡眠时间约为 8 毫秒。

我使用的是 Windows 11 设备。根据 python 时间文档,睡眠的分辨率为 100 纳秒(显然小于 10 毫秒)。对于

time.monotonic_ms()
,我无法找到解决方案。

我可以理解它怎么会超过指定的 10 毫秒,但我不知道它怎么会是 0 纳秒。 Python 版本:3.9.13.

我也在 3.12 上对此进行了测试,唯一的区别是当我尝试使用 CTRLC 停止执行时 IDLE 会冻结。

python time sleep
1个回答
0
投票

我通过对此答案的评论(根据用户“deceze ♦”此处的评论通过“链接跳跃”发现)知道了一个名为

time.get_clock_info
的函数。此函数提供多个时钟的时钟信息(在时间模块中)。

这是

time
的输出:

namespace(implementation='GetSystemTimeAsFileTime()', monotonic=False, adjustable=True, resolution=0.015625)

可以看出,正如我之前看到的,分辨率约为 16 毫秒。 显然

monotonic
monotonic_ns
的计时器(一般来说,所有
..._ns
计时器看起来只是非 ns 版本的专门变体)具有相同的分辨率(具有不同的基数):

namespace(implementation='GetTickCount64()', monotonic=True, adjustable=False, resolution=0.015625)

这仍然没有给出为什么它有时为零的答案。

perf_counter
具有更高的精度:

namespace(implementation='QueryPerformanceCounter()', monotonic=True, adjustable=False, resolution=1e-07)

process_time
perf_counter
具有相同的精度:

namespace(implementation='GetProcessTimes()', monotonic=True, adjustable=False, resolution=1e-07)

Python:Windows 11 Home 上的 3.9.13(Windows 版本似乎有所不同)

© www.soinside.com 2019 - 2024. All rights reserved.