首页   注册   登录
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/
V2EX  ›  Tornado

Tornado 异步怎么写的?

  •  
  •   aoscici2000 · 321 天前 · 1807 次点击
    这是一个创建于 321 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    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
        1
    mywaiting   321 天前
    Tornado 的 gen.corountine 里面如果要 sleep 必须用这个 tornado.gen.sleep()

    多点看看官方的文档,比网上的例子靠谱得多。网上很多的例子,很可能写例子本身的人就不懂 Tornadp

    文档链接 http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.sleep
        3
    aoscici2000   321 天前
    @zhengxiaowai 这篇好像也看过, 例子照做过, 但只要把他那个 gen.sleep() 改成自己要做的事情, 依然堵塞,,,
        4
    Vegetable   320 天前
    你自己要做的事情,必须也是 non-blocking 的.
    就比如这个 time.sleep,他阻塞了整个进程.而 gen.sleep 是非阻塞的,所以不会阻塞.
    所以数据库操作要用专门的异步驱动,网络操作要用 tornado 自己的异步 client 等等.
        5
    aoscici2000   320 天前
    @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()
        6
    Vegetable   320 天前
    @aoscici2000
    requests 是一个同步的客户端,你这个例子可以用 aiohttp 或者 tornado 的 AsyncHTTPClient 这种非阻塞的 HTTP 工具,IO 就不会阻塞了.耗时操作必须写成异步的,异步框架才有意义,不然还是会阻塞事件循环.
        7
    Aresn   320 天前
    用 Celery ?
        8
    zhengxiaowai   320 天前   ♥ 1
    @aoscici2000 仔细看构成异步的条件,简单来说只要 handle 中有一个耗时的步骤不是异步的,那么这个 handle 就不是异步的了。

    最简单的方法是使用 threadpoolexecutor
        9
    aoscici2000   319 天前
    @Aresn 新手, 还没接触这东西, 暂时也没时间哎
        10
    singed   289 天前
    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   289 天前
    楼主, 怎么贴有颜色的代码?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2193 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 41ms · UTC 12:56 · PVG 20:56 · LAX 05:56 · JFK 08:56
    ♥ Do have faith in what you're doing.