一:异步和非阻塞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_future
if chunk is None:break
self.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

        

 

    

  

tornado 第一篇的更多相关文章

  1. Python开发【第一篇】:目录

    本系列博文包含 Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习编程的童鞋提供一点帮助!!! Python开发[第一篇]:目录 Python开发[第二篇]:初识Python ...

  2. 第一篇 Flask

    第一篇 Flask     一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Ad ...

  3. Flask最强攻略 - 跟DragonFire学Flask - 第一篇 你好,我叫Flask

    首先,要看你学没学过Django 如果学过Django 的同学,请从头看到尾,如果没有学过Django的同学,并且不想学习Django的同学,轻饶过第一部分 一. Python 现阶段三大主流Web框 ...

  4. Python编程笔记(第一篇)Python基础语法

    一.python介绍 1.编程语言排行榜 TIOBE榜 TIOBE编程语言排行榜是编程语言流行趋势的一个指标,每月更新,这份排行榜排名基于互联网有经验的程序员.课程和第三方厂商的数量. 2.pytho ...

  5. 02: tornado进阶篇

    目录:Tornado其他篇 01: tornado基础篇 02: tornado进阶篇 03: 自定义异步非阻塞tornado框架 04: 打开tornado源码剖析处理过程 目录: 1.1 自定制t ...

  6. flask入门第一篇

    一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不 ...

  7. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)

    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...

  8. Python爬虫小白入门(四)PhatomJS+Selenium第一篇

    一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...

  9. Three.js 第一篇:绘制一个静态的3D球体

    第一篇就画一个球体吧 首先我们知道Three.js其实是一个3D的JS引擎,其中的强大之处就在于这个JS框架并不是依托于JQUERY来写的.那么,我们在写这一篇绘制3D球体的文章的时候,应该注意哪些地 ...

随机推荐

  1. PHP命名空间规则解析及高级功能3

    PHP命名空间规则解析及高级功能 -- : 来源:中国站长站综合 编辑:水色皇朝[纠错]1人评论 A-A+ 怎么开淘宝店 网站优化方法 创业如何获得投资 怎么做微商 最新LOL活动 日前发布的PHP ...

  2. ajax发送请求时为url添加参数(使用函数)

    <script> // ajax的get请求,使用函数向其url添加参数 function addURLParam(url,name,value){ url+=(url.indexOf(' ...

  3. scrapy-redis源代码分析

    原创文章,链接:http://blog.csdn.net/u012150179/article/details/38226253   +   (I) connection.py 负责依据setting ...

  4. Ubuntu Apache配置及开启mod_rewrite模块

    刚刚将服务器系统从CentOS换成Ubuntu,将MySQL,Apache,PHP和Wordpress安装好后,发现打开主页是正常的,但是打开文章页面时出现错误.因为使用了自定义的固定链接设置,那自然 ...

  5. Guardian of Decency UVALive - 3415 最大独立集=结点数-最大匹配数 老师带大学生旅游

    /** 题目:Guardian of Decency UVALive - 3415 最大独立集=结点数-最大匹配数 老师带大学生旅游 链接:https://vjudge.net/problem/UVA ...

  6. 下一个时代,对话即平台 —— 开始使用Bot Framework和Cognitive Service来打造你的智能对话服务

    在16年3月30号微软的全球开发者大会Build上发布了Bot Framework,微软认为下一个big thing是Conversation as a Platform,简称CaaP,中文应该叫做& ...

  7. php 计算时间添加

    $Date_1=date("Y-m-d");$Date_2="2015-10-11";$d1=strtotime($Date_1);$d2=strtotime( ...

  8. Java异常框架设计

    什么是异常? 异常(exception)应该是异常事件(exceptional event)的缩写.异常定义:异常是一个在程序执行期间发生的事件,它中断正在执行的程序的正常的指令流.当在一个方法中发生 ...

  9. [转]移动互联网应用技术架构简介-Restful服务

    Restful是基于网络的软件系统架构风格.其优先考虑分布性和扩展性,而不是安全.错误处理.对象映射. 所以Restful架构特别适用的场合为用户快速增长的互联网和移动互联网领域,看起来很容易理解,以 ...

  10. 蓝桥杯 第三届C/C++预赛真题(1) 微生物增值(数学题)

    假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍). 一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y. 现在已知有新 ...