Python 2.7中有什么类似于Go的“time.Tick”或Netty的“HashedWheelTimer”吗?

时间:2017-10-25 21:01:04

标签: python python-2.7 go 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)

然而,我注意到这个实现在长时间运行后引入了一些漂移(例如,我运行此代码大约10个小时,并注意到大约7秒的漂移)。对于我的工作,我需要在确切的秒上运行,毫秒甚至会更好。有些人指出我asyncio"Fire and forget" python async/await),但我无法在Python 2.7中使用它。

我不是在寻找黑客。我真正想要的是类似于Go time.Tick或Netty' HashedWheelTimer

1 个答案:

答案 0 :(得分:5)

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()

请注意,当您开始迭代时,上述自动收报机会开始计时,而不是在您调用tick时,如果您尝试启动自动收报机并将其保存以供日后使用。此外,它不发送时间,如果接收器很慢,它不会丢弃滴答。如果需要,您可以自行调整所有这些。