zoukankan      html  css  js  c++  java
  • Tornado异步与延迟任务

    最近一直在研究Tornado异步操作,然而一番研究后发现要使一个函数异步化的最好方法就是采用相关异步库,但目前很多功能强大的库都不在此列。经过一番查找文档和搜索示范,终于发现了ThreadPoolExecutor模块和run_on_executor装饰器。用法就是建立线程池,用run_on_executor装饰的函数即运行在其中线程中,从而从主线程中分离出来,达到异步的目的。
    另外,Tornado的IOLoop实例还有IOLoop.add_callback(callback, *args, **kwargs)方法,文档中的描述如下:

    Calls the given callback on the next I/O loop iteration.
    It is safe to call this method from any thread at any time, except from a signal handler. Note that this is the only method in IOLoop
    that makes this thread-safety guarantee; all other interaction with theIOLoop
    must be done from that IOLoop
    ‘s thread. add_callback()
    may be used to transfer control from other threads to the IOLoop
    ‘s thread.

    意思就是在执行add_callback方法后马上就会执行下一行代码,而callback函数将在下一轮事件循环中才调用,从而就能实现延迟任务。在Web APP中应付HTTP请求时,当有一些耗时操作并不需要返回给请求方时,就可以采用延迟任务的形式,比如发送提醒邮件。
    示范代码如下:

    #!/bin/env python
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import tornado.httpclient
    import tornado.gen
    from tornado.concurrent import run_on_executor
    # 这个并发库在python3自带;在python2需要安装sudo pip install futures
    from concurrent.futures import ThreadPoolExecutor
    import time
    from tornado.options import define, options
    define("port", default=8002, help="run on the given port", type=int)
    
    class SleepHandler(tornado.web.RequestHandler):
        executor = ThreadPoolExecutor(2)
    
        def get(self):
            tornado.ioloop.IOLoop.instance().add_callback(self.sleep)       # 这样将在下一轮事件循环执行self.sleep
            self.write("when i sleep")
    
        @run_on_executor
        def sleep(self):
            time.sleep(5)
            print("yes")
            return 5
    
    
    if __name__ == "__main__":
        tornado.options.parse_command_line()
        app = tornado.web.Application(handlers=[
                (r"/sleep", SleepHandler), ])
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()
    

    小礼物走一走,来简书关注我



    作者:不问喂神马
    链接:https://www.jianshu.com/p/3d20a092588d
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    Problem S: 分数类的模板数组类
    Problem E: 向量的运算
    Problem D: 强悍的矩阵运算来了
    Problem C: Person类与Student类的关系
    Problem B: 还会用继承吗?
    Problem A: 求个最大值
    Problem B: 数组类(II)
    树的直径题集
    LCA题集
    线段树总结
  • 原文地址:https://www.cnblogs.com/b02330224/p/10203350.html
Copyright © 2011-2022 走看看