比如说要等某个耗时操作的结果, 该怎么写?
网上看了半天例子, 照着做了做, 貌似行不通
class AsyncTaskHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous @tornado.gen.coroutine def get(self, *args, **kwargs): resp = yield tornado.gen.Task(self.do_something) self.finish(resp) @tornado.gen.coroutine def do_something(self, *args, **kwargs): time.sleep(10) return {'message': 'OKOK'}
![]() | 1 mywaiting 2018-12-02 13:23:57 +08:00 Tornado 的 gen.corountine 里面如果要 sleep 必须用这个 tornado.gen.sleep() 多点看看官方的文档,比网上的例子靠谱得多。网上很多的例子,很可能写例子本身的人就不懂 Tornadp 文档链接 http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.sleep |
![]() | 2 zhengxiaowai 2018-12-02 18:13:04 +08:00 |
3 aoscici2000 OP @zhengxiaowai 这篇好像也看过, 例子照做过, 但只要把他那个 gen.sleep() 改成自己要做的事情, 依然堵塞,,, |
![]() | 4 Vegetable 2018-12-02 23:03:19 +08:00 你自己要做的事情,必须也是 non-blocking 的. 就比如这个 time.sleep,他阻塞了整个进程.而 gen.sleep 是非阻塞的,所以不会阻塞. 所以数据库操作要用专门的异步驱动,网络操作要用 tornado 自己的异步 client 等等. |
5 aoscici2000 OP |
![]() | 6 Vegetable 2018-12-03 09:30:30 +08:00 @aoscici2000 requests 是一个同步的客户端,你这个例子可以用 aiohttp 或者 tornado 的 AsyncHTTPClient 这种非阻塞的 HTTP 工具,IO 就不会阻塞了.耗时操作必须写成异步的,异步框架才有意义,不然还是会阻塞事件循环. |
![]() | 7 Aresn 2018-12-03 09:32:44 +08:00 用 Celery ? |
![]() | 8 zhengxiaowai 2018-12-03 10:30:54 +08:00 ![]() @aoscici2000 仔细看构成异步的条件,简单来说只要 handle 中有一个耗时的步骤不是异步的,那么这个 handle 就不是异步的了。 最简单的方法是使用 threadpoolexecutor |
9 aoscici2000 OP @Aresn 新手, 还没接触这东西, 暂时也没时间哎 |
10 singed 2019-01-03 20:24:19 +08:00 import tornado.ioloop import tornado.web from tornado import gen from tornado.httpclient import AsyncHTTPClient class MainHandler(tornado.web.RequestHandler): def get(self): self.write("hello world") class ASyncHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): print("11111111111") self.write("hello world -------") class A2SyncHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): http_client = AsyncHTTPClient() print("777777777777") # http_client.fetch 会进入阻塞的方法, 切换协程 # respOnse= yield http_client.fetch("https://asia.playstation.com/hk") # res = response.body # 放开下面一行注释, /async 必须等这里跑完才会跑, 也会有被阻塞的感觉 res = str(jies(600)) # 不会进入阻塞的方法, 线程可能一直被这个函数占用了, # yield gen.sleep(10) 主动让出 10 秒执行权, 10 秒后回到这里执行 print("888888888888") self.write(res) application = tornado.web.Application([ (r"/", MainHandler), (r"/async", ASyncHandler), (r"/async2", A2SyncHandler)], ) def jies(n): for i in range(10**5): x = 1 return n*jies(n-1) if n != 1 else 1 if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start() |
11 singed 2019-01-03 20:25:42 +08:00 楼主, 怎么贴有颜色的代码? |