4

我想要的是能够每秒运行一个函数,与函数需要多长时间无关(它应该总是在一秒钟以下)。我考虑了许多选项,但不确定哪个是最好的。

如果我只使用延迟函数,它不会考虑函数运行所需的时间。

如果我对函数计时,然后从一秒中减去它并在延迟中弥补其余部分,则不会考虑时间计算。

我尝试使用 threading.timer(我不确定它的工作原理),但它似乎确实比 1s 慢。

这是我尝试测试 threading.timer 的代码:

def update(i):
    sys.stdout.write(str(i)+'\r')
    sys.stdout.flush()
    print i
    i += 1
    threading.Timer(1, update, [i]).start()

有没有办法做到这一点与函数花费的时间长度无关?

4

6 回答 6

9

这样就可以了,而且它的准确性不会随着时间的推移而漂移。

import time

start_time = time.time()
interval = 1
for i in range(20):
    time.sleep(start_time + i*interval - time.time())
    f()
于 2012-05-30T09:12:14.873 回答
7

实际上不应该使用使用 threading.Timer 的方法(参见下面的代码),因为每个时间间隔都会启动一个新线程,并且这个循环永远无法干净地停止。

# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
  threading.Timer(1, update, [i+1]).start()
  # business logic here

如果您想要一个后台循环,最好启动一个运行循环的新线程,如另一个答案中所述。哪个能够接收到停止信号,你join()最终可以线程。

这个相关的答案似乎是实现这一点的一个很好的起点。

于 2012-05-30T09:15:24.870 回答
3

如果f()总是花费不到一秒的时间,则在一秒的边界上运行它(没有漂移):

import time

while True:
    time.sleep(1 - time.monotonic() % 1)      
    f()

这个想法来自@Dave Rove 对类似问题的回答

要了解它是如何工作的,请考虑一个示例:

  1. time.monotonic()返回13.7并被time.sleep(0.3)调用
  2. f()大约(±一些错误)14秒(自time.monotonic()纪元以来)被调用
  3. f()运行,需要0.1(< 1) 秒
  4. time.monotonic()返回大约14.1几秒钟并被time.sleep(0.9)调用
  5. 15步骤 2. 在几秒钟左右重复(从time.monotonic()纪元开始)
  6. f()运行并且需要0.3(< 1) 秒(注意:该值与步骤 2 不同。)
  7. time.monotonic()返回15.3并被time.sleep(0.7)称为
  8. f()在几秒钟左右被调用16并重复循环。

每一步f()都在一秒钟的边界上调用(根据time.monotonic()计时器)。错误不会累积。没有漂移。

另请参阅:如何在 python 中定期运行函数(使用 tkinter)

于 2016-02-28T19:20:50.913 回答
1

这个怎么样:每次跑步后,睡(1.0 - launch interval)几秒钟。您可以通过更改来更改终止条件while True:。虽然如果你的函数运行时间超过 1 秒,这会出错。

from time import time, sleep

while True:
    startTime = time()
    yourFunction()
    endTime = time()-startTime
    sleep(1.0-endTime)
于 2012-05-30T09:29:55.323 回答
1

线程可能是一个不错的选择。基本概念如下。

import threading

def looper():    
    # i as interval in seconds    
    threading.Timer(i, looper).start()    
    # put your action here
    foo()

#to start 
looper()
于 2014-06-28T15:14:24.463 回答
-1

我想推荐以下代码。如果需要,您可以将 True 替换为任何条件。

while True:
time.sleep(1) #sleep for 1 second
func()    #function you want to trigger

告诉我它是否有效。

于 2020-03-31T06:53:01.313 回答