V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Tornado Documentation
http://www.v2ex.com/tornado/
Tornado on GitHub
https://github.com/facebook/tornado/
Tornado Gists
http://tornadogists.org/
aoscici2000
V2EX  ›  Tornado

Tornado 异步怎么写的?

  •  
  •   aoscici2000 · 2018-12-02 12:22:59 +08:00 · 8184 次点击
    这是一个创建于 2201 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如说要等某个耗时操作的结果, 该怎么写?

    网上看了半天例子, 照着做了做, 貌似行不通

    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'}
    
    11 条回复    2019-01-03 20:25:42 +08:00
    mywaiting
        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
    aoscici2000
        3
    aoscici2000  
    OP
       2018-12-02 19:47:17 +08:00
    @zhengxiaowai 这篇好像也看过, 例子照做过, 但只要把他那个 gen.sleep() 改成自己要做的事情, 依然堵塞,,,
    Vegetable
        4
    Vegetable  
       2018-12-02 23:03:19 +08:00
    你自己要做的事情,必须也是 non-blocking 的.
    就比如这个 time.sleep,他阻塞了整个进程.而 gen.sleep 是非阻塞的,所以不会阻塞.
    所以数据库操作要用专门的异步驱动,网络操作要用 tornado 自己的异步 client 等等.
    aoscici2000
        5
    aoscici2000  
    OP
       2018-12-03 01:40:03 +08:00
    @Vegetable 那假设我要耗时取得某些数据返回, 直接开个新线程去处理, 就算异步了? 例如:

    def get_db(self):
    data = requests.get('xxx.com')
    self.render('t.html', data=data)

    class GetDBHandler(MyHandler):
    @tornado.web.asynchronous
    def get(self):
    t = threading.Thread(target=get_db, args=(self,))
    t.start()
    Vegetable
        6
    Vegetable  
       2018-12-03 09:30:30 +08:00
    @aoscici2000
    requests 是一个同步的客户端,你这个例子可以用 aiohttp 或者 tornado 的 AsyncHTTPClient 这种非阻塞的 HTTP 工具,IO 就不会阻塞了.耗时操作必须写成异步的,异步框架才有意义,不然还是会阻塞事件循环.
    Aresn
        7
    Aresn  
       2018-12-03 09:32:44 +08:00
    用 Celery ?
    zhengxiaowai
        8
    zhengxiaowai  
       2018-12-03 10:30:54 +08:00   ❤️ 1
    @aoscici2000 仔细看构成异步的条件,简单来说只要 handle 中有一个耗时的步骤不是异步的,那么这个 handle 就不是异步的了。

    最简单的方法是使用 threadpoolexecutor
    aoscici2000
        9
    aoscici2000  
    OP
       2018-12-04 12:52:16 +08:00
    @Aresn 新手, 还没接触这东西, 暂时也没时间哎
    singed
        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()
    singed
        11
    singed  
       2019-01-03 20:25:42 +08:00
    楼主, 怎么贴有颜色的代码?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2663 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:33 · PVG 08:33 · LAX 16:33 · JFK 19:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.