zoukankan      html  css  js  c++  java
  • tornado异步

    tornado异步


    • Tornado默认是单进程单线程。实时的web特性通常需要为每个用户一个大部分时间都处于空闲的长连接. 在传统的同步web服务器中,这意味着需要给每个用户分配一个专用的线程,这样的开销是十分巨大的。

    • 为了减小对于并发连接需要的开销,Tornado使用了一种单线程事件循环的方式. 这意味着所有应用程序代码都应该是异步和非阻塞的,因为在同一时刻只有一个操作是有效的。

    • 当莫条请求被阻塞的时候,下一条请求将无法也会被阻塞住。针对这种情况,tornado提供了一种协程异步的方式来解决这种问题。
    •  1 from tornado.web import Application, RequestHandler
       2 from tornado.ioloop import IOLoop
       3 from tornado.httpserver import HTTPServer
       4 from tornado.httpclient import AsyncHTTPClient
       5 from tornado.options import options, define
       6 from tornado import gen
       7 
       8 define('port', default=80, type=int)
       9 
      10 
      11 
      12 class TestWebHandler(RequestHandler):
      13 
      14 
      15     """网络请求阻塞"""
      16     @gen.coroutine
      17     def get(self):
      18         client = AsyncHTTPClient()
      19         url = 'https://vdn1.vzuu.com/SD/bea84ccc-a09e-11e9-bf0c-0a580a436135.mp4?disable_local_cache=1&bu=com&expiration=1563118410&auth_key=1563118410-0-0-84c3390428629c25b0179da9964f294c&f=mp4&v=hw'
      20         res = yield client.fetch(url)
      21         with open('2.mp4', 'wb+') as f:
      22             f.write(res.body)
      23         self.write("下载完成!")
      24 
      25 class TestTimeHandler(RequestHandler):
      26 
      27     """time sleep阻塞"""
      28     @gen.coroutine
      29     def get(self):
      30         yield gen.sleep(5)
      31         self.write("TestTimeHandler page")
      32 
      33 
      34 class IndexHandle(RequestHandler):
      35     def get(self):
      36         self.write("index page")
      37 
      38 app = Application(
      39     handlers=[
      40         (r'/test', TestWebHandler),
      41         (r'/time', TestTimeHandler),
      42         (r'/', IndexHandle),
      43     ]
      44 )
      45 
      46 if __name__ == '__main__':
      47     options.parse_command_line()
      48     http = HTTPServer(app)
      49     http.listen(options.port)
      50     IOLoop.current().start()
    • 当网络阻塞的时候需要调用tornado的异步客户端,再调用gen.coroutine装饰器
    • 协同程序提供了一种在异步环境中工作比链接回调更简单的方法。使用协程的代码在技术上是异步的,但它是作为单个生成器而不是单独的函数集合编写的。
    • 当需要程序休眠的时候调用tornado内部提供的sleep方法,使用time.sleep不可以实现协程异步(time.sleep()是blocking的不支持异步操作)

      当异步函数有返回值时,接受该异步方法的函数也应该异步执行,用yield接受返回值

      

     1 from tornado.web import Application, RequestHandler
     2 from tornado.ioloop import IOLoop
     3 from tornado.httpserver import HTTPServer
     4 from tornado.options import options, define
     5 from tornado import gen
     6 
     7 define('port', default=80, type=int)
     8 
     9 
    10 class Test:
    11 
    12     @classmethod
    13     @gen.coroutine
    14     def get(self):
    15         yield gen.sleep(1)
    16         return "返回值"  # python3.3之后可以直接使用return, 3.3以前使用raise gen.Return
    17 
    18 
    19 class Index(RequestHandler):
    20     # 接受异步方法返回值的方法也应该异步,并且使用yield接受参数
    21     @gen.coroutine
    22     def get(self):
    23         resp =  yield Test.get()
    24         self.write(resp)
    25 
    26 
    27 
    28 app = Application(
    29     handlers=[
    30 
    31         (r'/', Index),
    32     ]
    33 )
    34 
    35 if __name__ == '__main__':
    36     options.parse_command_line()
    37     http = HTTPServer(app)
    38     http.listen(options.port)
    39     IOLoop.current().start()

     tornado协程的三种方式

     1 from tornado.web import RequestHandler, Application
     2 from tornado.httpserver import HTTPServer
     3 from tornado.ioloop import IOLoop
     4 from tornado.options import options
     5 from tornado import gen
     6 
     7 
     8 class IndexHandle(RequestHandler):
     9     @gen.coroutine
    10     def get(self):
    11         r1 = yield Index1Handle().get()
    12         print(r1)
    13         self.write(r1)
    14         r2 = yield Index2Handle().get()
    15         print(r2)
    16         self.write(r2)
    17         r3 = yield Index3Handle().get()
    18         print(r3)
    19         self.write(r3)
    20 
    21 
    22 class Index2Handle:
    23     @gen.coroutine
    24     def get(self):
    25         yield gen.sleep(5)
    26         return "666"
    27 
    28 
    29 class Index3Handle:
    30     async def get(self):
    31         await gen.sleep(5)
    32         return "666"
    33 
    34 
    35 class Index1Handle:
    36     @gen.coroutine
    37     def get(self):
    38         yield gen.sleep(5)
    39         raise gen.Return("666")
    40 
    41 
    42 app = Application(
    43     handlers=[
    44         (r'/', IndexHandle),
    45 
    46     ]
    47 )
    48 
    49 if __name__ == '__main__':
    50     options.parse_command_line()
    51     http = HTTPServer(app)
    52     http.listen(80)
    53     IOLoop.current().start()

      tornado官方文档:https://www.osgeo.cn/tornado/gen.html#decorators




  • 相关阅读:
    二元查找树转化成排序的双向链表——要求不创建新的节点
    MySQL 通配符学习小结
    HDU 1596 find the safest road (最短路)
    webapp开发调试环境--weinre配置
    全局钩子具体解释
    英尺到米的换算
    apache2.2 虚拟主机配置
    HTTP Digest authentication
    前端project师的修真秘籍(css、javascript和其他)
    CODE:BLOCK中的CreateProcess: No such file or directory
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/11186337.html
Copyright © 2011-2022 走看看