首頁  >  問答  >  主體

python - tornado怎么处理非常耗时的定时任务?

代码大致如下:

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_leeringa_lee2741 天前833

全部回覆(4)我來回復

  • PHP中文网

    PHP中文网2017-04-18 09:59:39

    聽起來這個任務會佔用主執行緒很久而且不確定具體耗時,那麼用協程顯然不合適。建議試試ThreadPoolExecutor,然後用yield threadPool.submit(fn)

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-18 09:59:39

    tornado自帶了gen模組, 其官網文檔有較為清晰的例子

    可以將其協程化. (用回調, 邏輯一複雜, 看程式碼很心累; 執行緒/進程, 要考慮調度問題)

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 09:59:39

    沒用的。 。如果不考慮別的,單線程,你要在一個地方耗時太久,那就是真的阻塞了。
    參考下面程式碼:

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

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-18 09:59:39

    取決於你的任務是網絡io密集型,還是本地io密集型/cpu密集型,如果是前者,只要使用PeriodicCallback就行了,如果是後者,建議實現一個queue,然後寫一個worker單獨跑任務

    回覆
    0
  • 取消回覆