首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >意外tornado.ioloop.PeriodicCallback行为

意外tornado.ioloop.PeriodicCallback行为
EN

Stack Overflow用户
提问于 2014-06-06 19:13:56
回答 2查看 7.5K关注 0票数 4

为了弄清PeriodicCallback的日程安排,我编写了以下脚本:

代码语言:javascript
复制
import time
import tornado.ioloop

t0 = time.time()

def foo():
    time.sleep(1)
    print(time.time() - t0)

tornado.ioloop.PeriodicCallback(foo, 2000).start()
tornado.ioloop.IOLoop.instance().start()

我期望它每隔2秒或每3秒发射一次,这取决于龙卷风是否要等到完成后才能安排下一次活动。然而,我得到的是:

代码语言:javascript
复制
3.00190114975
6.00296115875
10.0029530525
14.0029621124
18.0029540062
22.0050959587
26.0040180683
30.005161047
34.0053040981

这里发生了什么事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-06 19:27:30

我认为您只是看到了运行IOLoop的开销造成的延迟。例如,如果我将PeriodicCallback更改为每5秒运行一次,则得到以下输出:

代码语言:javascript
复制
6.00595116615
12.0075321198
17.0060141087
22.0051832199
27.0067241192
32.0061450005
37.0066981316
42.0063281059
47.0067460537

这和你所期望的差不多。另外,为了回答您最初的问题,PeriodicCallback在完成睡眠后安排了下一次回调(这是直接从龙卷风源代码中获取的):

代码语言:javascript
复制
class PeriodicCallback(object):
    def __init__(self, callback, callback_time, io_loop=None):
        self.callback = callback
        if callback_time <= 0:
            raise ValueError("Periodic callback must have a positive callback_time")
        self.callback_time = callback_time
        self.io_loop = io_loop or IOLoop.current()
        self._running = False
        self._timeout = None

    def start(self):
        """Starts the timer."""
        self._running = True
        self._next_timeout = self.io_loop.time()
        self._schedule_next()

    def _run(self):
        if not self._running:
            return
        try:
            self.callback() # Your function runs here.
        except Exception:
            app_log.error("Error in periodic callback", exc_info=True)
        self._schedule_next()  # Schedule next run after calling self.callback

    def _schedule_next(self):
        if self._running:
            current_time = self.io_loop.time()
            while self._next_timeout <= current_time:
                self._next_timeout += self.callback_time / 1000.0
            self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run) # The callback is actually scheduled with the ioloop here.
票数 4
EN

Stack Overflow用户

发布于 2014-06-06 22:40:42

在龙卷风应用程序中睡觉,即使是在“背景”PeriodicCallback中也不是一个好主意,因为它会阻塞IOLoop,并且会阻止它对事情进行适当的调度。如果使用的是“旋风”,则需要将所有长阻塞调用替换为非阻塞等价物(或将它们移动到其他线程)。用IOLoop.add_timeout代替睡眠,用IOStream或其他异步库替换网络操作,等等。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24089086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档