Asynchronous and non-Blocking I/O 翻译[收藏好文]
Real-time web features require a long-lived mostly-idle connection per user. In a traditional synchronous web server, this implies
devoting one thread to each user, which can be very expensive.
在同步状态下,实时的网络请求会一直占用着一个空的连接,这样每一个用户都会占用着一个线程,很浪费
To minimize the cost of concurrent connections, Tornado uses a single-threaded event loop. This means that all application code should aim to be asynchronous and non-blocking because only one operation can be active at a time.
为了最大限度的利用连接,Tornado使用单线程事件循环的方式。就是使应用采用异步和非阻塞的方式保持着当下只有一个活动的事件,同时又能接收多个应用请求。
The terms asynchronous and non-blocking are closely related and are often used interchangeably, but they are not quite the same thing.
异步和非阻塞这两个术语通常意思一样,但是他们也有不同的地方。
Blocking
A function blocks when it waits for something to happen before returning. A function may block for many reasons: network I/O, disk I/O, mutexes, etc. In fact, every function blocks, at least a little bit, while it is running and using the CPU (for an extreme example that demonstrates why CPU blocking must be taken as seriously as other kinds of blocking, consider password hashing functions like bcrypt, which by design use hundreds of milliseconds of CPU time, far more than a typical network or disk access).
等待这个功能模块返回结果前,函数有很多阻塞的原因,比如:网络I/O、磁盘I/O、互斥操作等。事实上每个功能模块在它运行的时候都会使用一点CPU资源(CPU阻塞必须要当做其它类型的阻塞)
A function can be blocking in some respects and non-blocking in others. For example, tornado.httpclient in the default configuration blocks on DNS resolution but not on other network access (to mitigate this use ThreadedResolver or a tornado.curl_httpclient with a properly-configured build of libcurl). In the context of Tornado we generally talk about blocking in the context of network I/O, although all kinds of blocking are to be minimized.
函数能在一些方面阻塞,在另一些方面不阻塞,**,在Tornado下我们一般讨论的是网络I/O阻塞,其它情况都是很小的。 Tornado里面讨论的阻塞都是指网络阻塞,其它的阻塞可以忽略。*
Asynchronous
An asynchronous function returns before it is finished, and generally causes some work to happen in the background before triggering some future action in the application (as opposed to normal synchronous functions, which do everything they are going to do before returning). There are many styles of asynchronous interfaces:
异步函数会在执行结束之前返回,在完成之后通常是一些后台程序去触发预先设定好的处理程序(不像同步程序,必须都做完了才返回)。下面列举了很多种风格的异步接口。
- Callback argument 回调参数
- Return a placeholder (Future, Promise, Deferred) 返回一个占位符
- Deliver to a queue 交付到队列中
- Callback registry (e.g. POSIX signals) 回调到注册表中
Regardless of which type of interface is used, asynchronous functions by definition interact differently with their callers; there is no free way to make a synchronous function asynchronous in a way that is transparent to its callers (systems like gevent use lightweight threads to offer performance comparable to asynchronous systems, but they do not actually make things asynchronous).
无论使用哪种接口,异步函数都会使用不同的方式与调用者交互;没有办法去定义一个同步函数却采用异步的方式调用,对于调用者来说都是透明的(就像采用gevent的轻量级线程系统去提供做到的性能堪比异步系统,但它实际上并不是异步)。
这句话的意思就是说同步的方法没法用异步的方式去调,虽然你写的代码看起来像是异步的,但其实并不是。
Examples
Here is a sample synchronous function:
下面的例子是一个同步函数。
|
1
2
3
4
5
6
|
from tornado.httpclient import HTTPClient
def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body
|
And here is the same function rewritten to be asynchronous with a callback argument:
下面的例子被重写成异步的方式了,采用了回调参数的方式。
|
1
2
3
4
5
6
7
|
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)
|
And again with a Future instead of a callback:
下面的例子通过返回一个展位符的方式实现异步回调的。
|
1
2
3
4
5
6
7
8
9
|
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
|
The raw Future version is more complex, but Futures are nonetheless recommended practice in Tornado because they have two major advantages. Error handling is more consistent since the Future.result method can simply raise an exception (as opposed to the ad-hoc error handling common in callback-oriented interfaces), and Futures lend themselves well to use with coroutines. Coroutines will be discussed in depth in the next section of this guide. Here is the coroutine version of our sample function, which is very similar to the original synchronous version:
通过Future的方式实现的更复杂,但是Tornado更建议这样去写,主要有两个原因。从Future返回的错误处理更一致,从Future.result方法可以返回一个简单的异常,Future能够更好的与协同程序一起使用。协同程序的具体讨论将会在下一节讨论,下面的例子给了一个协同程序的例子,写法很像同步的那个版本。
|
1
2
3
4
5
6
7
|
from tornado import gen
@gen.coroutine
def fetch_coroutine(url):
http_client = AsyncHTTPClient()
response = yield http_client.fetch(url)
raise gen.Return(response.body)
|
The statement raise gen.Return(response.body) is an artifact of Python 2, in which generators aren’t allowed to return values. To overcome this, Tornado coroutines raise a special kind of exception called a Return. The coroutine catches this exception and treats it like a returned value. In Python 3.3 and later, a return response.body achieves the same result.
这个版本中返回一个raise gen.Return(response.body),在Python2中的用法,因为生成器不允许返回一个值,所以Tornado做了特殊处理,通过跑出一个Return的异常,然后协同程序补货这个异常,就相当于返回值了。在Python3.3以后就可以直接返回这个值了。
Translated by zhangxu on 2016-08-05
Asynchronous and non-Blocking I/O 翻译[收藏好文]的更多相关文章
- 中文翻译:pjsip文档(四)之ICE Session的使用方法
1:pjsip教程(一)之PJNATH简介 2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介 3:pjsip教程(三)之ICE ...
- YUV视频格式详解(翻译自微软文档)
原文: https://docs.microsoft.com/en-us/previous-versions/aa904813(v=vs.80) YUV视频格式详解(翻译自微软文档)https://b ...
- [翻译] Autofac 入门文档
原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: 用控制反转(IoC)的思想 ...
- HugePages概述--翻译自19C文档
翻译自: https://docs.oracle.com/en/database/oracle/oracle-database/19/unxar/administering-oracle-databa ...
- 使用 Python 翻译 CHM 帮助文档
此方法绝对切实可行 翻译成品项目: https://github.com/foyoux/InstallShield2020-Documents 效果预览 安装 docts 库 pip install ...
- React翻译官网文档之JSX
什么是JSX? 看下面的代码它被称为JSX,它既不是字符串也不是HTML,而是一种facebook公司对javascript语法的拓展.虽然写法很奇怪最终仍会会被编译为javascript代码 con ...
- 翻译:SockJS-node文档(一)
什么是SockJS? SockJS是一个提供Websocket通信的JavaScript库,目的是实现在浏览器与服务器之间低延迟.全双工.跨域通信,它提供跨浏览器的统一API,即使不支持HTML5 W ...
- Why should I avoid blocking the Event Loop and the Worker Pool?
Don't Block the Event Loop (or the Worker Pool) | Node.js https://nodejs.org/en/docs/guides/dont-blo ...
- 基于百度翻译API开发属于自己的翻译工具
你是否每天使用着网页翻译工具?你是否遇到过这种情况,上网过程中遇到一个很长的单词但是又不能复制,要开两个浏览器,一个打开百度翻译,照着另一个网页输入单词?你安装了各种翻译软件后,又删除,只因忍受不了那 ...
随机推荐
- 准确率,召回率,F值,机器学习分类问题的评价指标
下面简单列举几种常用的推荐系统评测指标: 1.准确率与召回率(Precision & Recall) 准确率和召回率是广泛用于信息检索和统计学分类领域的两个度量值,用来评价结果的质量.其中精度 ...
- Android中使用Handler以及CountDownTimer实现包括倒计时的闪屏页面
上一篇博文<Android中Handler使用浅析>通过实现倒计时闪屏页面的制作引出了Handler的用法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友能够点击链接回去看看 ...
- innerWidth outerWidth
在jQuery中: 一.width()方法用于获得元素宽度: 二.innerWidth()方法用于获得包括内边界(padding)的元素宽度; 三.outerWidth()方法用于获得包括内边界(pa ...
- GPUImage简单滤镜使用之色阶(三)
色阶是表示图像亮度强弱的指数标准,图像的色彩丰满度和精细度是由色阶决定的.在GPUImage中GPUImageLevelsFilter提供了此功能. GPUImageLevelsFilter定义了修改 ...
- 自定义Spring注解bean的命名策略
由于项目的需要spring的业务相关的bean不是写在xml文件中,因为项目是一个模块一个模块提交的,提交的时候不想修改xml文件,因此就用到了spring的注解Service. 例如: Java代码 ...
- Jquery 中的CheckBox、 RadioButton、 DropDownList的取值赋值
1.获取选中值,三种方法都可以: $('input:radio:checked').val(): $("input[type='radio']:checked").val(); $ ...
- ZH奶酪:HTML元素文本溢出显示省略号(...)
一 单行文本 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow 属性规定当内容溢出元素框时发生的事情. ...
- sharepoint 2010 怎样在Ribbon区加入功能button
继续前面的一篇博客,sharepoint 2010 怎样在列表中加入功能菜单操作项.这次主要是记录下,在Ribbon区域加入功能button.比如加入收藏button.例如以下图所看到的: 1. 还是 ...
- python xlsxwriter写excel并操作各种格式属性
# -*- coding: utf-8 -*- import xlsxwriter workbook = xlsxwriter.Workbook('test.xlsx') worksheet = wo ...
- Definitaion of 'utsname' must be imported from module 'Darwin.POSIX.sys.utsname' before it is required
https://stackoverflow.com/questions/34430354/objective-c-gettimeofday-must-be-imported