Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[译]Tornado异步非阻塞I/O

[译]Tornado异步非阻塞I/O

作者头像
Jintao Zhang
发布于 2018-08-27 07:06:53
发布于 2018-08-27 07:06:53
1.1K0
举报
文章被收录于专栏:MoeLoveMoeLove

译者说

Tornado 4.3于2015年11月6日发布,该版本正式支持Python3.5async/await关键字,并且用旧版本CPython编译Tornado同样可以使用这两个关键字,这无疑是一种进步。其次,这是最后一个支持Python2.6Python3.2的版本了,在后续的版本了会移除对它们的兼容。现在网络上还没有Tornado4.3的中文文档,所以为了让更多的朋友能接触并学习到它,我开始了这个翻译项目,希望感兴趣的小伙伴可以一起参与翻译,项目地址是tornado-zh on Github,翻译好的文档在Read the Docs上直接可以看到。欢迎Issues or PR。

异步和非阻塞I/O

实时web功能需要为每个用户提供一个多数时间被闲置的长连接,在传统的同步web服务器中,这意味着要为每个用户提供一个线程,当然每个线程的开销都是很昂贵的.

为了尽量减少并发连接造成的开销,Tornado使用了一种单线程事件循环的方式.这就意味着所有的应用代码都应该是异步非阻塞的,因为在同一时间只有一个操作是有效的.

异步和非阻塞是非常相关的并且这两个术语经常交换使用,但它们不是完全相同的事情.

阻塞

一个函数在等待某些事情的返回值的时候会被 阻塞. 函数被阻塞的原因有很多:网络I/O,磁盘I/O,互斥锁等.事实上 每个 函数在运行和使用CPU的时候都或多或少会被阻塞(举个极端的例子来说明为什么对待CPU阻塞要和对待一般阻塞一样的严肃: 比如密码哈希函数bcrypt, 需要消耗几百毫秒的CPU时间,这已经远远超过了一般的网络或者磁盘请求时间了).

一个函数可以在某些方面阻塞在另外一些方面不阻塞.例如, tornado.httpclient 在默认的配置下,会在DNS解析上面阻塞,但是在其他网络请求的时候不阻塞(为了减轻这种影响,可以用 ThreadedResolver 或者是通过正确配置 libcurltornado.curl_httpclient 来做).在Tornado的上下文中,我们一般讨论网络I/O上下文的阻塞,尽管各种阻塞已经被最小化了.

异步

异步 函数在会在完成之前返回,在应用中触发下一个动作之前通常会在后台执行一些工作(和正常的 同步 函数在返回前就执行完所有的事情不同).这里列举了几种风格的异步接口:

  • 回调参数
  • 返回一个占位符 (.Future, Promise, Deferred)
  • 传送给一个队列
  • 回调注册表 (POSIX信号)

不论使用哪种类型的接口, 按照定义 异步函数与它们的调用者都有着不同的交互方式;也没有什么对调用者透明的方式使得同步函数异步(类似 gevent使用轻量级线程的系统性能虽然堪比异步系统,但它们并没有真正的让事情异步).

例子

一个简单的同步函数:

代码语言:javascript
AI代码解释
复制
    from tornado.httpclient import HTTPClient

    def synchronous_fetch(url):
        http_client = HTTPClient()
        response = http_client.fetch(url)
        return response.body

把上面的例子用回调参数重写的异步函数:

代码语言:javascript
AI代码解释
复制
    from tornado.httpclient import AsyncHTTPClient

    def asynchronous_fetch(url, callback):
        http_client = AsyncHTTPClient()
        def handle_response(response):
            callback(response.body)
        http_client.fetch(url, callback=handle_response)

使用 Future 代替回调:

代码语言:javascript
AI代码解释
复制
    from tornado.concurrent import Future

    def async_fetch_future(url):
        http_client = AsyncHTTPClient()
        my_future = Future()
        fetch_future = http_client.fetch(url)
        fetch_future.add_done_callback(
            lambda f: my_future.set_result(f.result()))
        return my_future

Future 版本明显更加复杂,但是 Futures 却是Tornado中推荐的写法.因为它有两个主要的优势.首先是错误处理更加一致,因为 Future.result 方法可以简单的抛出异常(相较于常见的回调函数接口特别指定错误处理),而且 Futures 很适合和协程一起使用.协程会在后面深入讨论.这里是上面例子的协程版本,和最初的同步版本很像:

代码语言:javascript
AI代码解释
复制
    from tornado import gen

    @gen.coroutine
    def fetch_coroutine(url):
        http_client = AsyncHTTPClient()
        response = yield http_client.fetch(url)
        raise gen.Return(response.body)

raise gen.Return(response.body) 声明是在Python 2 (and 3.2)下人为执行的, 因为在其中生成器不允许返回值.为了克服这个问题,Tornado的协程抛出一种特殊的叫 Return 的异常. 协程捕获这个异常并把它作为返回值.在Python 3.3和更高版本,使用 return response.body 有相同的结果.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MoeLove 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
利用世界杯,读懂 Python 装饰器
6 月 17 日德国战墨西哥,小痴虽然是一个伪球迷,但每年的世界杯还是会了解下。而德国是上届的冠军,又是这届夺冠热门。德意志战车在 32 年间小组赛就没有输过!卧槽!虽然小痴很少赌球,但这次德国如此强大,肯定会赢吧。搏一搏单车变摩托!随后小痴买了德国队赢。心里想着这次肯定稳了!赢了会所嫩模!小痴连比赛都不看,美滋滋的敲着代码。
猫咪编程
2018/07/20
4190
一文读懂Python装饰器由来(一)
Python装饰器是非常不错的特性,熟练掌握装饰器会让你的编程思路更加宽广,程序也更加pythonic。下面就让我们一起来探讨一下python的装饰器吧。
Python中文社区
2018/07/26
5250
Python3 装饰器理解
谈装饰器之前,需明白一件事,Python 中的函数和 Java、C++ 不一样,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数,代码示例如下:
嵌入式视觉
2022/09/05
2700
python中的装饰器decorator
而我们想为这三个函数增加一个函数调用打印功能 类似print("call f1()")
py3study
2020/01/15
6540
Python装饰器详解
装饰器本质就是函数,作用是装饰其它函数,给其它函数增加附加功能,提高代码复用,减少代码量。
王大力测试进阶之路
2019/10/25
4550
4.python迭代器生成器装饰器
基本概念 1.容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有: list, deque, …. set, frozensets, …. dict, defaultdict, OrderedDict, Counter, …. tuple, namedtupl
zhang_derek
2018/04/11
6620
python基础----装饰器
本文介绍了装饰器在Python中的基本概念和使用方法,通过一个具体的例子阐述了装饰器如何在函数调用前后添加额外的功能,并指出使用装饰器的好处在于可以在不修改原函数的基础上动态增加功能。同时,本文还介绍了如何编写装饰器,并给出一个复杂的例子,使读者对装饰器有更深入的了解。
GavinZhou
2018/01/02
5240
一文搞定Python装饰器,看完面试不再慌
差不多五年前面试的时候,我就领教过它的重要性。那时候我Python刚刚初学乍练,看完了廖雪峰大神的博客,就去面试了。我应聘的并不是一个Python的开发岗位,但是JD当中写到了需要熟悉Python。我看网上的面经说到Python经常会问装饰器,我当时想的是装饰器我已经看过了,应该问题不大……
TechFlow-承志
2020/04/28
1.5K0
python之yield与装饰器
  在之前发布的《python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作。
py3study
2020/01/06
4810
python装饰器
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584
ke1th
2019/08/29
5480
python3--装饰器
# Author: Aaron Fan """ 装饰器(别名:语法糖): 定义:    本质是函数(装饰其它函数),就是为其它函数添加一些附件的功能 原则:    1、不能修改被装饰的函数的源代码    2、不能修改被装饰的函数的调用方式    3、装饰器存在对被装饰的函数是完全透明的(就是被装饰的函数完全感觉不到装饰器的存在) 实现装饰器的只是储备: 1、函数就是变量 2、高阶函数 3、嵌套函数 高阶函数 + 嵌套函数 == 装饰器 """ import time def timer(
py3study
2020/01/03
3610
python高级-装饰器(19)
某公司有多个研发部⻔,1个基础平台部⻔,基础平台负责提供底层的功能,如:数据库操作、redis调⽤、监控API等功能。研发部⻔使⽤基础功能时,只需调⽤基础平台提供的功能即可。如下:
Se7eN_HOU
2019/09/11
4650
python高级-装饰器(19)
对Python中装饰器(Decorator)
  有时候我们项目中的某些功能做些修改即需要对内部的某些函数添加一些附加功能,但是为了安全起见不想改变函数的源代码以及函数的调用方式,那么装饰器在这个地方会给我们带来很大的帮助。
py3study
2020/01/09
3440
python 装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不雲要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
py3study
2018/08/02
5470
python_类装饰器
一.定义 装饰器就是一个给对象添加额外功能的函数,其本质是函数。它的基本构造:高阶函数+函数嵌套+闭包。 二.简单类的装饰器 我们先看简单的类的装饰器,如果我们需要给任意一个类添加一个打印功能,即:没当操作这个类时,就打印”定义了一个装饰类函数”,见下图:
py3study
2020/01/06
2.1K0
python 3层装饰器及应用场景
    1)把一个函数名当做实参传给另一个函数(在不修改被装饰函数的源代码情况下为其添加功能);
py3study
2020/01/03
5510
装饰器、生成器,迭代器、Json & pickle 数据序列化
1、 列表生成器:代码例子 1 a=[i*2 for i in range(10)] 2 print(a) 3 4 运行效果如下: 5 D:\python35\python.exe D:/pytho
coders
2018/01/04
6930
装饰器、生成器,迭代器、Json & pickle 数据序列化
Python装饰器
由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
小破孩的梦想空间
2020/04/23
4940
了解Python装饰器
一 装饰器是什么 装饰器是一个用于封装函数或者类的代码工具,显式地将封装器作用于函数或者类上,达到程序运行时动态增加功能的目的。对于函数运行前处理常见前置条件(常见的web登陆授权验证),或者在函数执行之后做善后工作(比如异常处理,记录log 等等)。 二 如何使用装饰器 装饰器本质上就是一个可用接受调用也可以返回调用的高阶函数。该函数以被装饰的函数为参数(还可以加上其他值作为参数)。在装饰器内进行装饰器的逻辑处理,执行被装饰函数,并返回一个装饰过的函数,听起来是不是有点绕,Talk is cheap,show me the code . 本文使用函数now 和函数add作为例子,
用户1278550
2018/08/09
4560
Python学习(五)---- 不可不知的装饰器!
https://blog.csdn.net/fgf00/article/details/52061971
智能算法
2018/08/17
4920
相关推荐
利用世界杯,读懂 Python 装饰器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档