1. 使用gen.coroutine 异步编程

  • 在python3中使用gen.coroutine来实现异步编程:效果和 async await 一样
  • coroutine装饰器可以指定请求为协程模式,可以配合yield 实现异步编程

    1. class SleepHandler(BaseHandler):
    2. """异步的延时10秒的接口"""
    3. @gen.coroutine
    4. def get(self):
    5. yield gen.sleep(10)
    6. self.write("when i sleep 5")
  • 使用coroutine 有个明显的缺点是:严重依赖第三方库,如果第三方库本身不支持Tornado 的异步操作再怎么使用协程也是会阻塞的。

    2. 基于线程的异步编程

  • 在tornado 中使用装饰器ThreadPoolExecutor 来让阻塞过程变成非阻塞,原理是:在Tornado 本身这个线程的之外上再启动一个线程来处理这个阻塞的程序。

    1. class ThreadSleepHandler(BaseHandler):
    2. """time库不支持tornado异步"""
    3. # 必须定义一个executor的属性,然后run_on_executor 注解才管用。
    4. executor = ThreadPoolExecutor(max_workers=4)
    5. @gen.coroutine
    6. def get(self):
    7. yield self.sleep_fun()
    8. self.write("when i sleep 10s")
    9. @run_on_executor
    10. def sleep_fun(self):
    11. time.sleep(5)
  • 随着而来的问题是:如果大量使用线程化的异步函数来处理一些高负载的程序,会导致Tornado 性能下降。所以在处理一些小负载的情况下,是比较合理的。

    3. Python原生的协程 async await 关键字

    1. class IndexHandler(BaseHander):
    2. async def get(self):
    3. await asyncio.time(10)
    4. self.write("hello world)

    4. 使用celery 实现异步