1. 使用gen.coroutine 异步编程
- 在python3中使用gen.coroutine来实现异步编程:效果和 async await 一样
coroutine装饰器可以指定请求为协程模式,可以配合yield 实现异步编程
class SleepHandler(BaseHandler):
"""异步的延时10秒的接口"""
@gen.coroutine
def get(self):
yield gen.sleep(10)
self.write("when i sleep 5")
使用coroutine 有个明显的缺点是:严重依赖第三方库,如果第三方库本身不支持Tornado 的异步操作再怎么使用协程也是会阻塞的。
2. 基于线程的异步编程
在tornado 中使用装饰器ThreadPoolExecutor 来让阻塞过程变成非阻塞,原理是:在Tornado 本身这个线程的之外上再启动一个线程来处理这个阻塞的程序。
class ThreadSleepHandler(BaseHandler):
"""time库不支持tornado异步"""
# 必须定义一个executor的属性,然后run_on_executor 注解才管用。
executor = ThreadPoolExecutor(max_workers=4)
@gen.coroutine
def get(self):
yield self.sleep_fun()
self.write("when i sleep 10s")
@run_on_executor
def sleep_fun(self):
time.sleep(5)
随着而来的问题是:如果大量使用线程化的异步函数来处理一些高负载的程序,会导致Tornado 性能下降。所以在处理一些小负载的情况下,是比较合理的。
3. Python原生的协程 async await 关键字
class IndexHandler(BaseHander):
async def get(self):
await asyncio.time(10)
self.write("hello world)
4. 使用celery 实现异步