理解 tornado.gen
转自:http://blog.xiaogaozi.org/2012/09/21/understanding-tornado-dot-gen/
理解 tornado.gen
SEP 21ST, 2012
Tornado 通过 @asynchronous
decorator 来实现异步请求,但使用的时候必须将 request handler 和 callback 分离开,tornado.gen
模块可以帮助我们在一个函数里完成这两个工作。下面是官方的一个例子:
1 |
|
这里用到了两个 decorator 稍显复杂,第一个 @asynchronous
会首先被执行,它的主要工作就是将 RequestHandler
的 _auto_finish
属性置为 false
,如下:
web.pydownload
1 |
|
接着就是最重要的 @gen.engine
,这里充分利用了 generator 的各种特性,首先来看 @gen.engine
的实现(我删减了部分代码以简化理解):
gen.pydownload
1 |
|
局部变量 gen
代表第一段代码里的 get
函数,因为 get
包含了 yield
语句,因此成为了一个 generator。注意这里 get
并没有被执行,只是赋给了 gen
。接下来是运行 Runner
对象的 run
函数。在理解 run
之前需要知道 generator 是通过调用 next()
或者 send()
来启动,启动之后会在遇到 yield
的地方 hold 住,然后将 yield
后面的语句的返回值返回给调用者,generator 此时即处于暂停运行状态,所有上下文都会保存。再次调用 next()
或 send()
便会恢复 generator 的运行,如果不再遇到 yield
语句就会抛出 StopIteration
异常。在恢复运行的同时 yield
语句本身会有返回值,如果是通过调用 next()
来恢复的,那么返回值永远是 None
,而如果是通过 send()
则返回值取决于传给 send()
的参数。更多关于 generator 的说明请参考官方文档。
结合第一段的示例代码,可以想到 run
干的工作可能就是启动 generator,然后获得 gen.Task
对象并调用 http_client.fetch
函数,等回调回来之后恢复 generator 的运行,最后将回调的返回值通过 send()
赋给 response
。下面是我简化后的代码。
gen.pydownload
1 |
|
第 3 行检查回调是否完成,第一次运行 run
总是会返回 True
。第 5 行获取回调的返回值,同样的第一次运行返回的是 None
。将 None
传给 send()
启动 generator,yielded
即是 gen.Task
对象,第 12 行调用 start
开始运行我们真正需要运行的函数,对应到示例代码就是http_client.fetch
函数,同时将 Runner
的 result_callback
作为回调函数。如下:
gen.pydownload
1 |
|
在得到回调返回值之后再次调用 run
,通过 get_result
获取返回值,最后将返回值返回赋给 response
,继续 request handler 的代码流程。
理解 tornado.gen的更多相关文章
- tornado.gen 模块解析
转自:http://strawhatfy.github.io/2015/07/22/Tornado.gen/ 引言 注:正文中引用的 Tornado 代码除特别说明外,都默认引用自 Tornado 4 ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- Tornado @tornado.gen.coroutine 与 yield
在使用 Tornado 的过程中产生了以下疑问: 什么时候需要给函数增加 @tornado.gen.coroutine 什么时候调用函数需要 yield @tornado.gen.coroutine ...
- Python之路(四十一):通过项目来深入理解tornado
Tornado之路 引子 与其感慨路难行,不如马上出发 目录 通过项目来深入理解tornado(一):tornado基础回顾 通过项目来深入理解tornado(二):AsyncHttpClient ...
- 如何捕捉@tornado.gen.coroutine里的异常
from tornado import gen from tornado.ioloop import IOLoop @gen.coroutine def throw(a,b): try: a/b ra ...
- 理解tornado
计算密集型:多进程 IO密集型:多线程 能产生IO阻塞的情况很多,比如网络通讯.磁盘读写.当发生阻塞时,CPU是闲置的,此时如果就一个线程就没法处理其他事情了. 所以对于含有IO阻塞的环境,多线程 ...
- tornado.gen.coroutine-协程
http://blog.csdn.net/seeground/article/details/49488281
- 深入理解yield(三):yield与基于Tornado的异步回调
转自:http://beginman.cn/python/2015/04/06/yield-via-Tornado/ 作者:BeginMan 版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须 ...
- tornado 杂记
一.建立一个简单的 hello world 网页 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import tornado.iolo ...
随机推荐
- Android Mms专题之:Mms源码结构
从软件的功能角度来讲,Mms分为对话列表,消息列表,短信编辑,彩信编辑,短信显示,彩信显示和配置. 从实现的角度来看,它分为GUI展示层,发送/接收,彩信解析,彩信附件,信息数据等,这些分类对应着源码 ...
- IOS UIImage两种初始化的区别
UIImage可以通过以下两种方式进行初始化: 1 //第一种初始化方式:[注意使用这种初始化的时候如果是png格式的可以不给后缀名,根据屏幕的的分辨率去匹配图片] 2 3 UIImage *imag ...
- S3TC IAP15F2K61S2点亮一个发光二极管keil和stc-isp软件操作
1.安装破解软件 2.打开STC-ISP,找到头文件,选择保存文件 3.找到keil的安装目录,keil/C51/INC 并保存 4.在桌面新建文件夹 5.打开keil 6.找到在桌面上新建的文件夹 ...
- caffe测试mnist问题-error while loading shared libraries
问题描述 build/examples/mnist/convert_mnist_data.bin: error while loading shared libraries: libcudart.so ...
- m函数与m文件的命名
问题 创建函数test_image,按照定义方式进行调用,一直出现下图所示的错误, 调试的过程中一直提示输入参数太多,可是test_image这个函数的输入个数和调用这个函数的输入输出数目是一致的,然 ...
- STM32中TIMx的映射及其通道
TIMx,通道x,无映射,部分映射,完全映射 TIM1_CH1, PA8, PE9, TIM1_CH2, PA9, PE11 TIM1_CH3, PA10, PE1 ...
- spring boot下mybatis遇到No operations allowed after connection closed.
在配置文件中添加 # for initial,min,maxspring.datasource.initialSize=5spring.datasource.minIdle=5spring.datas ...
- hdu1428 记忆化搜索(BFS预处理最短路径和+DP+DFS)
题意:有一块 n * n 大小的方形区域,要从左上角 (1,1)走到右下角(n,n),每个格子都有通过所需的时间,并且每次所走的下一格到终点的最短时间必须比当前格子走到重点的最短时间短,问一共有多少种 ...
- BL老师的建议,数学不好的,大数据一票否决--后赋从java转大数据
__________________________ 作者:我是蛋蛋链接:https://www.zhihu.com/question/59593387/answer/167235075来源:知乎著作 ...
- HTML图片热区map area的用法
<area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: < ...