比如说要等某个耗时操作的结果, 该怎么写?
网上看了半天例子, 照着做了做, 貌似行不通
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 1
@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
楼主, 怎么贴有颜色的代码?
|