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 次的输出是:
这是在窗户上。我现在正在运行它 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的主要内容,如果未能解决你的问题,请参考以下文章