nmu*_*thy 3 python go python-2.7 python-asyncio concurrent.futures
我写了很多依赖于精确的周期性方法调用的代码.我一直在使用Python的futures库将调用提交到运行时的线程池,并在循环中的调用之间休眠:
executor = ThreadPoolExecutor(max_workers=cpu_count())
def remote_call():
# make a synchronous bunch of HTTP requests
def loop():
while True:
# do work here
executor.submit(remote_call)
time.sleep(60*5)
Run Code Online (Sandbox Code Playgroud)
但是,我注意到这个实现在长时间运行后引入了一些漂移(例如,我运行此代码大约10个小时,并注意到大约7秒的漂移).对于我的工作,我需要在确切的秒上运行,毫秒甚至更好.有些人指出我asyncio("火与忘记"python async/await),但我无法在Python 2.7中使用它.
我不是在寻找黑客.我真正想要的是类似于Go time.Tick或Netty的东西HashedWheelTimer.
没有像Python那样的东西.您需要手动调整睡眠时间以计算工作时间.
你可以把它折叠成迭代器,就像Go的频道一样time.Tick:
import itertools
import time
import timeit
def tick(interval, initial_wait=False):
# time.perf_counter would probably be more appropriate on Python 3
start = timeit.default_timer()
if not initial_wait:
# yield immediately instead of sleeping
yield
for i in itertools.count(1):
time.sleep(start + i*interval - timeit.default_timer())
yield
for _ in tick(300):
# Will execute every 5 minutes, accounting for time spent in the loop body.
do_stuff()
Run Code Online (Sandbox Code Playgroud)
请注意,当您开始迭代时,上述自动收报机开始计时,而不是在您打电话时tick,如果您尝试启动自动收报机并将其保存以供日后使用.此外,它不发送时间,如果接收器很慢,它不会丢弃滴答.如果需要,您可以自行调整所有这些.