我想要的是能够每秒运行一个函数,与函数花费的时间无关(它应该始终低于一秒)。我考虑了很多选择,但不确定哪种选择最好。
如果我只使用延迟功能,则不会考虑该功能运行的时间。
如果我对函数进行计时,然后从一秒钟中减去该函数并在延迟中弥补其余部分,则不会考虑时间计算。
我尝试使用threading.timer(我不确定这是如何工作的来龙去脉)但它似乎比1更慢。
这是我尝试测试threading.timer的代码:
def update(i):
sys.stdout.write(str(i)+'\r')
sys.stdout.flush()
print i
i += 1
threading.Timer(1, update, [i]).start()
有没有办法与函数所用的时间长度无关?
答案 0 :(得分:6)
使用threading.Timer(参见下面的代码)的方法实际上应该不被使用,因为每个时间间隔都会启动一个新的线程,并且这个循环永远不会被彻底停止。
# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
threading.Timer(1, update, [i+1]).start()
# business logic here
如果你想要一个后台循环,最好启动一个运行循环的新线程,如另一个答案所述。哪个能够接收到停止信号,s.t。你最终可以join()
线程。
This related answer似乎是实现这一目标的一个很好的起点。
答案 1 :(得分:4)
这样做,它的准确性不会随着时间的推移而漂移。
import time
start_time = time.time()
interval = 1
for i in range(20):
time.sleep(start_time + i*interval - time.time())
f()
答案 2 :(得分: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)
答案 3 :(得分:1)
线程可能是一个不错的选择。基本概念如下。
import threading
def looper():
# i as interval in seconds
threading.Timer(i, looper).start()
# put your action here
foo()
#to start
looper()
答案 4 :(得分:1)
如果f()
总是需要不到一秒钟,那么在一秒边界上运行它(没有漂移):
import time
while True:
time.sleep(1 - time.monotonic() % 1))
f()
这个想法来自@Dave Rove's answer to a similar question。
要了解它是如何工作的,请考虑一个例子:
time.monotonic()
返回13.7
,time.sleep(0.3)
被称为f()
被调用(±某些错误)14
秒(自time.monotonic()
纪元以来)f()
正在运行,需要0.1
(<1)秒time.monotonic()
返回14.1
秒,time.sleep(0.9)
称为15
纪元time.monotonic()
秒重复执行第2步
f()
正在运行,需要0.3
(&lt; 1)秒(注意:该值与步骤2不同。)time.monotonic()
返回15.3
,time.sleep(0.7)
称为f()
秒左右调用16
并重复循环。在每个步骤f()
上调用一秒边界(根据time.monotonic()
计时器)。错误不会累积。没有漂移。
另请参阅:How to run a function periodically in python (using tkinter)。
答案 5 :(得分:0)
import time
lastSecond = 0
while True:
while time.time() % 1 > 0.1:
time.sleep(0.1)
now = int(time.time())
if now % 60 != lastSecond:
print now
lastSecond = now % 60
答案 6 :(得分:0)
我想推荐以下代码。您可以根据需要将True替换为任何条件。
while True:
time.sleep(1) #sleep for 1 second
func() #function you want to trigger
告诉我是否可行。