python - tornado怎么处理非常耗时的定时任务?
ringa_lee
ringa_lee 2017-04-18 09:57:39
0
4
839

代码大致如下:

class MainHandler(RequestHandler):
    def get(self):
        ...
        ...
        
        
def update():
    ...
    ...
    IOLoop.instance().add_timeout(time.time() + 3600, update)
    
   
if __name__ == '__main__':
    application = tornado.web.Application([
        ....
    ])
    server = HTTPServer(application)
    server.start(2) # 开启两个进程
    IOLoop.instance().add_timeout(time.time() + 3600, update)  # 耗时的定时update
    ...
    ...

其中update()是一个特别耗时的任务
目前的做法是加大add_timeout的时间间隔,以避免两个进程全都去做update了

因为对异步编程并不熟,所以想请教一下有没有更合适的做法

ringa_lee
ringa_lee

ringa_lee

全部回复(4)
Ty80

听起来这个任务会占用主线程很久而且不确定具体耗时,那么用协程显然不合适。建议试试ThreadPoolExecutor,然后用yield threadPool.submit(fn)

左手右手慢动作

tornado自带了gen模块, 其官网文档有较为清晰的例子

可以将其协程化. (用回调, 逻辑一复杂, 看代码很心累; 线程/进程, 要考虑调度问题)

伊谢尔伦

没用的。。如果不考虑别的,单线程,你要在一个地方耗时太久,那就是真的阻塞了。
参考下面代码:

class TestHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        yield gen.Task(self.sleep)
        self.write('ok')
        self.finish()

    def sleep(self, callback):
        for i in range(100000000):
            if i % 100000 == 0:
                pass
        print('ooo')
        callback()
大家讲道理

取决于你的任务是网络io密集型,还是本地io密集型/cpu密集型,如果是前者,只要使用PeriodicCallback就行了,如果是后者,建议实现一个queue,然后写一个worker单独跑任务

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!