有没有办法阻止计时器的蠕变?

2024-09-30 00:39:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法,以每秒钟运行一个方法,不管它需要多长时间运行。我跑过去找人帮忙

Run certain code every n seconds

在尝试中,发现它不能正常工作。它似乎有一个我正试图避免的问题:漂移。我试着在打印后加上一个“sleep(0.5)”,它确实减慢了循环的速度,并且间隔时间保持在1.003(大约)秒。在

有没有办法解决这个问题,做我想做的事?在

(venv) 20170728-153445 mpeck@bilbo:~/dev/whiskerlabs/aphid/loadtest$ cat a.py
import threading
import time
def woof():
  threading.Timer(1.0, woof).start()
  print "Hello at %s" % time.time()
woof()
(venv) 20170728-153449 mpeck@bilbo:~/dev/whiskerlabs/aphid/loadtest$ python a.py
Hello at 1501281291.84
Hello at 1501281292.85
Hello at 1501281293.85
Hello at 1501281294.85
Hello at 1501281295.86
Hello at 1501281296.86
Hello at 1501281297.86
Hello at 1501281298.87
Hello at 1501281299.87
Hello at 1501281300.88
Hello at 1501281301.88
Hello at 1501281302.89
Hello at 1501281303.89
Hello at 1501281304.89
Hello at 1501281305.89
Hello at 1501281306.9
Hello at 1501281307.9
Hello at 1501281308.9
Hello at 1501281309.91
Hello at 1501281310.91
Hello at 1501281311.91
Hello at 1501281312.91
Hello at 1501281313.92
Hello at 1501281314.92
Hello at 1501281315.92
Hello at 1501281316.93

Tags: 方法pydevimporthellovenvtimeat
2条回答

我很确定这段代码的问题是Python需要一些时间(显然大约是.3s)来执行对函数woof的调用,实例化一个新的threading.Timer对象,并打印当前时间。因此,基本上,在您第一次调用函数并创建threading.Timer之后,Python将等待1s,然后调用函数woof(大约一个分秒),创建一个新的Timer对象(至少还有一个分秒),最后延迟打印当前时间。在

实际上每秒钟运行一个程序的解决方案似乎是Twisted库,正如在this other post上所说的,但是我自己并没有真正尝试过。。。在

编辑:我会将问题标记为可能的重复问题,但我显然还没有足够的声誉来做这件事。。。如果有人能用我提供的链接这么做,那就太酷了:)

  1. 如果每次都不需要一个新线程,就不要使用threading.Timer;要周期性地运行一个函数,sleep在一个循环中就可以了(可能在一个单独的线程中)。

  2. 无论您使用什么方法来计划下一次执行,都不要等待您使用的确切时间量,因为其他语句的执行需要时间,因此您可以看到结果是漂移的。相反,在变量中记下初始时间,并在每次迭代时计算下一次要调度执行和睡眠的时间,以计算现在和那时之间的差异。在

    interval = 1.
    next_t = time.time()
    while True:
        next_t += interval
        time.sleep(next_t - time.time())
        # do whatever you want to do 
    

    (当然,您可以对其进行改进以获得更好的总体精度,但这至少应避免偏移)

相关问题 更多 >

    热门问题