文章目录
在Tornado
中,要使一个任务,我们经常需要用Tornado
自己的异步模块,或者适配Tornado
的第三方异步模块。
但很多情况下我们需要的功能模块可能没有适配Tornado
的异步模型,然后我们自己又不可能造一个轮子。
这个时候,我们就可以使用Tornado
自带的通过线程来将同步方法异步化。
虽然Tornado
是单线程异步的Web框架,但是它也提供了使用线程来将同步任务异步化的装饰器。
在tornado.concurrent
这个模块中有一个装饰器run_on_executor
,使用它装饰在请求处理器的方法上,来使用线程将该同步任务异步话。
下面给出示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
import time import concurrent.futures
import tornado.web import tornado.concurrent import tornado.ioloop import tornado.gen
class AsyncHandler(tornado.web.RequestHandler):
executor = concurrent.futures.ThreadPoolExecutor(4)
@tornado.gen.coroutine def get(self): futures = [self.sleep(1) for i in range(8)] results = yield futures print(results)
@tornado.concurrent.run_on_executor def sleep(self, sec): time.sleep(sec) return time.time()
pass
if __name__ == "__main__": app = tornado.web.Application([(r"/", AsyncHandler)]) app.listen(8000) tornado.ioloop.IOLoop.current().start()
|
启动Web服务后,访问/
。
1 2
| jzqt@Dreamer:~$ curl localhost:8000/ [1467202920.2401285, 1467202920.240263, 1467202920.2402115, 1467202920.2403257, 1467202921.240244, 1467202921.2412646, 1467202921.2413185, 1467202921.241381]
|
可以看出,同步任务确实是异步化了。上面的用例是通过线程池来异步的,更多的使用方法就不多讲了,可以研究官方文档等。
注意:计算密集型任务使用线程优化作用不大,因为Python有GIL大家懂得。