Python - 准确的 time.sleep

Posted

技术标签:

【中文标题】Python - 准确的 time.sleep【英文标题】:Python - Accurate time.sleep 【发布时间】:2018-11-03 20:51:20 【问题描述】:

我正在做一个项目,准确的计时器非常重要。我正在研究python 并正在使用timer.sleep() 函数。

我注意到timer.sleep()函数会因为调度问题增加额外的延迟(参考timer.sleep docs)。由于这个问题,我的程序运行时间越长,计时器就越不准确。

有没有更准确的计时器/计时器让程序休眠或解决这个问题?

任何帮助将不胜感激。干杯。

【问题讨论】:

我认为没有,因为操作系统调度程序正在做自己的事情。不过,我正在饶有兴趣地关注这个问题。 在 linux 上是 0.001 毫秒不准确。在 Windows 上,大约 16 毫秒是不准确的。这是因为操作系统,我不知道有什么更好的解决方案。我想会关注这个问题。 您是否尝试为您的进程提供实时优先级?准确性是非确定性系统的问题,但 linux 可以真正接近大多数需求。你愿意容忍多少延迟?女士,我们,ns?时间受限的解决方案总是难以交付且非常脆弱,对代码、内核或运行时的任何更改通常都会影响此类解决方案。 您使用的是什么操作系统?看到这个c++ 问题:Precise thread sleep needed. Max 1ms error 您是否多次调用timer.sleep(“我的程序运行时间越长,计时器越不准确”)?如果是这样,您能否通过使用 time.clock_gettime 之类的方式跟踪实际时间来纠正睡眠时间? 【参考方案1】:

在 Windows 零知识的情况下在 Linux 上工作,我可能在这里很天真,但是否有一些原因让你自己编写睡眠函数对你不起作用? 比如:

import time

def sleep_time():
    start_time = time.time()
    while (time.time() - start_time) < 0.0001:
        continue

end_time = time.time() + 60 # run for a minute
cnt = 0
while time.time() < end_time:
    cnt += 1
    print('sleeping',cnt)
    sleep_time()
    print('Awake')
print("Slept ",cnt," Times")

【讨论】:

这会杀死 CPU。 详细地说,busy-looping 有时是低级编程中的正确解决方案,但鉴于他正在编写 Python,这肯定不是 OP 的情况。 @jbch 确实如此!鉴于OP的困境,当魔鬼开车时,需求必须。这是一个选择,如果有点重。【参考方案2】:

我有一个类似于上面的解决方案,但它很快就变得很重。这是一个重处理器的想法和解决方法。

def processor_heavy_sleep(ms):  # fine for ms, starts to work the computer hard in second range.
    start = time.clock()
    end = start + ms /1000.
    while time.clock() < end:
        continue
    return start, time.clock()


def efficient_sleep(secs, expected_inaccuracy=0.5):  # for longer times
    start = time.clock()
    end = secs + start
    time.sleep(secs - expected_inaccuracy)
    while time.clock() < end:
        continue
    return start, time.clock()

efficient_sleep(5, 0.5) 3 次的输出是:

(3.1999303695151594e-07, 5.0000003199930365) (5.00005983869791, 10.00005983869791) (10.000092477987678, 15.000092477987678)

这是在窗户上。我现在正在运行它 100 个循环。这是结果。

(485.003749358414, 490.003749358414) (490.0037919174879, 495.0037922374809) (495.00382903668014, 500.00382903668014)

睡眠保持准确,但呼叫总是稍有延迟。如果您需要一个调度程序,它可以准确地调用每 xxx 秒到毫秒,那将是另一回事。

【讨论】:

【参考方案3】:

我的程序运行的时间越长,计时器就越不准确。

因此,例如,预计 0.5 秒延迟,它将是 time.sleep(0.5 - (start-end))。但还是没有解决问题

您似乎在抱怨两种影响,1) timer.sleep() 可能需要比您预期更长的时间,以及 2) 使用一系列 timer.sleep() 调用的内在蠕变。

除了切换到实时操作系统之外,您对第一个操作无能为力。底层操作系统调用被定义为在请求时休眠至少。他们只保证你不会早起;他们不保证你不会起晚。

至于第二个,你应该根据一个不变的时代来计算你的睡眠时间,而不是你的起床时间。例如:

import time
import random

target = time.time()
def myticker():
    # Sleep for 0.5s between tasks, with no creep
    target += 0.5
    now = time.time()
    if target > now:
        time.sleep(target - now)


def main():
    previous = time.time()
    for _ in range(100):
        now = time.time()
        print(now - previous)
        previous = now
        # simulate some work
        time.sleep(random.random() / 10)  # Always < tick frequency
        # time.sleep(random.random())     # Not always < tick frequency
        myticker()

if __name__ == "__main__":
    main()

【讨论】:

以上是关于Python - 准确的 time.sleep的主要内容,如果未能解决你的问题,请参考以下文章

Python绘制loss曲线准确率曲线

使用 OpenCV 和 Python 准确寻找水域边缘

Python Pandas 条件无法准确识别行

无法在 Python 上准确计算 pi

如何在python中测量knn分类器的准确性

使用python代码读取准确性而不是tensorboard