Python Tornado 异步和非阻塞I/O
来源:互联网 发布:淘宝8.8 编辑:程序博客网 时间:2024/06/05 19:51
Tornado 4.3文档翻译: 用户指南-异步和非阻塞I/O
译者说
Tornado 4.3
于2015年11月6日发布,该版本正式支持 Python3.5
的 async
/ await
关键字,并且用旧版本CPython编译Tornado同样可以使用这两个关键字,这无疑是一种进步。其次,这是最后一个支持 Python2.6
和 Python3.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
或者是通过正确配置 libcurl
用 tornado.curl_httpclient
来做).在Tornado的上下文中,我们一般讨论网络I/O上下文的阻塞,尽管各种阻塞已经被最小化了.
异步
异步函数在会在完成之前返回,在应用中触发下一个动作之前通常会在后台执行一些工作(和正常的 同步 函数在返回前就执行完所有的事情不同).这里列举了几种风格的异步接口:
回调参数
返回一个占位符 (
.Future
,Promise
,Deferred
)传送给一个队列
回调注册表 (POSIX信号)
不论使用哪种类型的接口, 按照定义 异步函数与它们的调用者都有着不同的交互方式;也没有什么对调用者透明的方式使得同步函数异步(类似 gevent 使用轻量级线程的系统性能虽然堪比异步系统,但它们并没有真正的让事情异步).
例子
一个简单的同步函数:
from tornado.httpclient import HTTPClient def synchronous_fetch(url): http_client = HTTPClient() response = http_client.fetch(url) return response.body
把上面的例子用回调参数重写的异步函数:
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
代替回调:
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
很适合和协程一起使用.协程会在后面深入讨论.这里是上面例子的协程版本,和最初的同步版本很像:
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
有相同的结果.
- Python Tornado 异步和非阻塞I/O
- Tornado用户指引(一)-----------异步和非阻塞I/O
- I/O模型:同步I/O和异步I/O,阻塞I/O和非阻塞I/O
- 阻塞与非阻塞I/O,I/O复用,同步和异步I/O
- 同步异步阻塞非阻塞I/O
- I/O 阻塞&非阻塞&同步&异步
- 网络IPC非阻塞和异步I/O
- Thrift 非阻塞异步I/O例子
- 阻塞式I/0 和 非阻塞式I/O 同步异步详细介绍
- 操作系统I/O:阻塞和非阻塞
- socket同步和异步、阻塞和非阻塞、I/O模型
- 浅谈socket同步和异步、阻塞和非阻塞、I/O模型_php技巧
- 非阻塞I/O和阻塞I/O
- 阻塞I/O和非阻塞I/O
- 阻塞I/O和非阻塞I/O
- tornado异步请求非阻塞
- Tornado 异步非阻塞 分析
- tornado 异步非阻塞 实验
- 放盘子-2016"百度之星" - 测试赛(热身,陈题)
- 解决tomcat上运行servlet使用jdbc异常的问题
- wifidog源码分析 - 客户端检测线程
- Linux 安装Tomcat指定JDK
- linux2.6.32.71如何在lcd上显示内核启动信息
- Python Tornado 异步和非阻塞I/O
- 学习小组小记
- wifidog源码分析 - 认证服务器心跳检测线程
- selenium---sl4j日志输出
- 如何在安卓中把方形图变成圆形图
- 第十一周补充项目4-日期和时间类
- JavaScript事件委托的技术原理
- nyoj559 报数游戏
- kernel启动流程