tornado 第一篇
一:异步和非阻塞IO
实时的web特性通常需要每个用户一个大部分时间,在传统的同步web服务器中,这意味着需要给每个用户分配一个专用的线程,这样的开销是十分巨大
tornado使用啦一种单线程事件循环的方式,这意味着所有的应用代码都应该是异步和非阻塞的,因为在同一时刻只有一个操作是有效的
1,阻塞
一个函数在等到返回值等都是阻塞的,
一个函数可以在某些方面阻塞而在其他方面不阻塞,举例说明。tornado,httpclient在默认设置下讲阻塞与DNS解析,但是在其他网络请求时不会阻塞(为了减轻这种影响,可以用ThreadeResolver 或通过正确配置libcurl使用tornado.curl_htpclient),在Tornado的上下文中我们通常讨论网络I/O上下文阻塞,虽然各种阻塞已经被最小化啦
2,异步
一个异步函数在在它结束前就已经返回啦,而且通常会在程序中触发一些动作然后在后头执行一些任务,这里有几种类型的异步接口
1,回调函数
2,返回一个占位符(Future,Promise,Deferred)
3,传送一个队列
4,回调注册
一个简单的同步异步函数
from tornado.httpclient import HTTPClient from tornado.concurrent import Future def synchronous_fetch(url):http_client = HTTPClient()def handle_response(response):callback(response.body)http_client.fetch(url,callbace=handle_response)
在一次通过Future替代回调函数
def async_fetch_future(url):http_client=HTTPClient()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 函数可以简单抛出一个异常,还有就是携程兼容比较好
rom 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 中是人为设定的, 因为生成器不允许又返回值. 为了克服这个问题, Tornado 协程抛出了一个叫做 Return
的特殊异常. 协程将会像返回一个值一样处理这个异常.在 Python 3.3+ 中, return response.body
将会达到同样的效果.
二:协程
tornado中推荐协程来编写异步代码,协程使用python中关键件yield替换链式回调实现挂起和继续协程的执行(像在gevent中使用轻量级线程合作的方法有时也称作为协程,但是在Tornado中所有的协程使用异步函数来实现明确的上下文切换)
看下协程的代码
from tornado import gen from tornado import HTTPClient def fetch_coroutie(url):http_client=AsyncHTTPClient() respone=yield http_client.fetch(url) # raise gen.Return(respone.body) return respone.body
python3.5 async和awiat
python3.5 引入啦async和await 从tornado4.3开始,在协程基础上你可以使用这个来代替yield,简单的通过使用async def foo()来替代 @gen.coroutine 装饰器,用await来代替yield,可以看下下面的例子
async def fetch_coroutine(url):http_client = AsyncHTTPClient()response = await http_client.fetch(url)return response.body
一个含有yield的函数时是一个生成器,所有的生成器都是异步的,调用它时将会返回一个对象而不是将函数运行完成,@gen.coroutine修饰器通过yeild表达式通过产生一个Future对象和生成器进行通信
可以看下一个协程装饰器内部循环的简单版本
def run(self):future=self.gen.send(self.next)def callback(f):self.next=f.result()self.run()future.add_done_callback(callback)
有时你并不想等待一个协程的返回值. 在这种情况下我们推荐你使用 IOLoop.spawn_callback
, 这意味着 IOLoop
负责调用. 如果它失败了, IOLoop
会在日志中记录调用栈: 同时注意spawn_callback调用的函数,也必须是协程函数
# The IOLoop will catch the exception and print a stack trace in # the logs. Note that this doesn't look like a normal call, since # we pass the function object to be called by the IOLoop.IOLoop.current().spawn_callback(divide, 1, 0) 协程模式 1,结合callbacks 为了使用回调来代替Future与异步代码进行交互,将这个调用装在task中,这将会在你生成的Future对象中添加一个回调参数
@gen.coroutine def call_task():yield gen.Task(some_function, other_args)#把yeild换成gen_Task
2,调用阻塞函数
在协程中调用阻塞函数的最简单方法是使用ThreadPoolExecutor 这将返回与协程兼容的Futures
thread_pool = ThreadPoolExecutor(4)@gen.coroutine def call_blocking():yield thread_pool.submit(blocking_func, args)
3,并行
协程装饰器识别列表或者字典中的Futures,并且并行等待这些Fuures
@gen.coroutine def parallel_fetch(url1,url2):resp1,resp2 = yield [http_client.fetch(url1),http_client.fetch(url2)]@gen.coroutine def parallel_fetch_dict(urls):responses = yield {url: http_client.fetch(url)for url in urls}
4,交叉存取技术(项目一般用到比较多)
有时保存一个Future比立刻yield它更有用,你可以等待它之前执行其他操作
def get(self):fetch_future = self.fetch_next_chunk()while True:chunk = yield fetch_futureif chunk is None:breakself.write(chunk)fetch_future= self.fetch_next_chunk()yield self.flush()
5,循环
因为python无法使用forwhile循环yield迭代器,并且捕获yield的返回结果,相反,你需要将循环和访问结果区分开来,
import motor db = motor.MotorClient().test@gen.coroutine def loop_example(collection):cursor = db.collection.find()while (yield cursor.fetch_next):doc = cursor.next_object()
6,在后台运行
@gen.coroutine def minute_loop():while True:yield do_something()yield gen.sleep(60)# Coroutines that loop forever are generally started with # spawn_callback(). IOLoop.current().spawn_callback(minute_loop)
更过内容可以参考:http://tornado-zh-cn.readthedocs.io/zh_CN/latest/guide/coroutines.html#python-3-5-async-await
转载于:https://www.cnblogs.com/1204guo/p/8533421.html
tornado 第一篇相关推荐
- 属于窄带噪声的是热噪声_时钟201系列: 非相位噪声的情况 (第一篇)
欢迎来到Silicon Labs(亦称"芯科科技")的新系列博客文章"时钟201"的第一篇内容-非相位噪声的情况-第一部分.我们之前的系列博文"时钟1 ...
- linux的自定义input,Linux Input子系统之第一篇(input_dev/input_handle/input_handler)
Input子系统是linux kernel中与部分外围器件驱动联系比较紧密的模块,常用于Sensor,TP(touch panel),power key等器件的驱动.这类模块有个共同特点:字符设备,且 ...
- 第一篇文章,做个纪念
第一篇文章,做个纪念,这个blog好吗?拭目以待! 转载于:https://blog.51cto.com/197536/88241
- 《Ansible权威指南 》一 第一篇 Part 1 基础入门篇
本节书摘来自华章出版社<Ansible权威指南 >一书中的第1章,第1.1节,李松涛 魏 巍 甘 捷 著更多章节内容可以访问云栖社区"华章计算机"公众号查看. 第一篇 ...
- 研究生第一篇科研论文常犯问题总结
↑ 点击蓝字 关注视学算法 作者丨喻海良,中南大学教授,博士生导师 来源|http://blog.sciencenet.cn/blog-117889-1018759.html 极市导读 本文作者为中南 ...
- Webpack系列-第一篇基础杂记
系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 公司的前端项目基本都是用Webpack来做工程化的,而Webpack虽然 ...
- 蒟蒻的第一篇博客CF1041C Coffee Break(二分+贪心+set)
CF1041C Coffee Break(二分+贪心+set) 描述 Recently Monocarp got a job. His working day lasts exactly mm min ...
- Spotify敏捷模式详解三部曲第一篇:研发团队
本文转自:Scrum中文网 引言 2018年4月,来自北欧瑞典的音乐流媒体公司.百亿美元独角兽Spotify创造了历史,它成为了当代上市公司当中,第一家通过"直接上市"的方式在美国 ...
- 第一篇:UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xc3 in position 0: invalid continuation byt
第一篇:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: invalid continuation byt ...
最新文章
- matlab中读文件的行数_[转载]MATLAB中获取大型文本文件行数方法研究(转)
- java.lang.NullPointerException错误分析
- 三维匹配_机器视觉——双目视觉的基础知识(视差深度、标定、立体匹配)
- 医疗:ICU(10)
- 推荐算法--总结(08)
- Android emulator error: x86 emulation currently requires hardware acceleration的解决方案
- nginx服务器配置安全维护,nginx 安全:如何强化服务器配置
- mint ui css覆盖,vue中配置mint-ui报css错误问题的解决方法
- 【气动学】基于matlab GUI外弹道仿真系统【含Matlab源码 1044期】
- java提供两种处理异常的机制_Java的异常机制分析及处理办法
- [渝粤教育] 湘潭大学 计算机组成与体系结构 参考 资料
- 笔记本计算机管理没有键盘,如何禁用笔记本键盘输入?怎么关闭笔记本键盘
- 【数字图像处理】【个人入门记录】 绪论
- android 点击状态栏,“点击状态栏回到顶部”功能的消失原因和实现
- 网站页面的颜色和线条搭配
- android守护进程详解
- App Store Review Guidelines中文版-上部
- python缩进可以用在任何语句之后_Python程序中,缩进表达所属关系,在缩进的前一行最后,需要使用符号 Python 语句中增...
- 做一个九宫格诗词答题小程序 (二)倒计时功能实现
- 破解微信图片防盗链 微信图片不显示怎么办?
热门文章
- python括号匹配问题_支持通配符的括号匹配问题源码+详细流程代码(python)
- mysql redis hbase_MySQL之基本介绍
- python3 爬虫 requests安装_BOSS直聘招聘信息获取之爬虫工具分析
- 中list如何清空_如何根据索引删除 list 中的元素
- Error occurred while trying to proxy request
- jps显示当前所有java进程pid
- TP-Link路由器设置上网知识笔记
- 收集实用的MySQL使用技巧
- 曲线的生成算法实现_PCGPlanet1-地形生成算法简介
- python的flag是什么意思_网上老说的flag是什么意思