python:如何定期进行非阻塞查找

时间:2017-06-26 21:06:02

标签: python python-3.x nonblocking python-asyncio periodic-task

请你定期告知如何定期 执行一个比周期性间隔需要更多时间执行的任务?

例如:

def lookup():
    # do some lookups, retrieve info, let's assume it takes 60sec to complete
    msg = {'abc':123}
    time.sleep(60)
    return msg

class Publisher(object):
    def __init__(self):
        self._TIMEIT = 0
        self._INTERVAL = 5
        self._counter = 0

    def xxx():
        t_start = time.time()
        msg = lookup()
        # do something with the value returned
        save_msg_to_db(msg)
        self._counter += 1
        t_end = time.time()
        self._TIMEIT = int(math.ceil(t_end - t_start))

    def run():
        while True:
            # let's do the lookup every 5sec, but remember that lookup takes 60sec to complete
            time.sleep(self._INTERVAL)
            # the call to xxx() should be non-blocking
            xxx()

run方法负责安排定期任务, 并且当它迭代时,它不应该在调用函数xxx时阻塞。

我正在考虑在每次调用xxx函数时创建一个事件循环,如A Bad Coroutine Example中所述但是如何调用xxx非阻塞?

PS。我正在使用Python3.4新的asyncio(过去使用gevent),不确定我是否在这里问愚蠢。

所以lookup会创建一个异步循环,让我们假设60秒完成。但是,在run方法中有一个无限循环运行,我希望它每隔5秒进行一次查找,换句话说我想(1)我多久调用一次查找函数,独立(2)完成查找需要多长时间

1 个答案:

答案 0 :(得分:0)

由于您的lookup()主要是I / O密集型,因此您可以将xxx()方法作为一个线程运行并且完全正常(代码简化为了简洁):

import threading
import time

class Publisher(object):

    def __init__(self):
        self._INTERVAL = 5
        self._counter = 0
        self._mutex = threading.Lock()

    def xxx(self):
        msg = lookup()
        save_msg_to_db(msg)
        with self._mutex:  # make sure only one thread is modifying counter at a given time
            self._counter += 1

    def run(self):
        while True:
            time.sleep(self._INTERVAL)
            t = threading.Thread(target=self.xxx)
            t.setDaemon(True)  # so we don't need to track/join threads
            t.start()  # start the thread, this is non-blocking