Read-time(实时)的网站需要针对每个用户保持长时间的连接。在传统的同步网站服务中,通常针对每个用户开启来一个线程来实现,但是这样做非常昂贵。

为了使并发连接的成本最小化,Tornada使用单个线程事件循环机制。这样意味着所有的的应用程序的目标都是异步且非阻塞的,因为在同一事件只有一个线程是活动的。

异步和非阻塞非常相近而且经常可交换使用,但是他们确实不是一个东西。

4.1 阻塞

函数阻塞时,这个函数会一直等待处理的结果返回。一个函数会因为多种情况阻塞,比如网络I/O,硬盘I/O等等。事实上,每一个函数都会阻塞,最少是一点点,因为他们在运行而且要使用Cpu(最有代表性的是密码hash函数bcrypt,要使用cpu的毫秒时间)。

一个函数在一些情况下会阻塞,但是在另外一些情况下不会阻塞。举个例子来说,tornado.httpclient 在DNS解决方案下,当采取默认的配置时会阻塞,但是在其他网络访问的情况下不会阻塞(比如使用ThreadedResolver 或者tornado.curl_httpclient)。

4.2 异步

一个异步的函数在函数结束之前就可以返回,通常在触发一些未来的动作之前会引起后台处理处理一些工作。下面有几种异步接口:

  • Callback 参数(回调函数)
  • 返回一个占位符(比如Future、Promise、Deferred)
  • 发送至一个队列中(Queue)
  • 回调注册(POSIX signals)

示例:

下面是一段同步函数的示例。

from tornado.httpclient import HTTPClient

def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body

下面是用带有CallBack参数重写的异步函数,实现同一功能。

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版本更复杂,但是Tornado用Futures作为推荐的最佳实践方式,因为Futures用两大主要的优点。其一,错误处理表现更加一致,因为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(及3.2)的实现方式,但是生成器不允许返回值。为了克服这个问题,Tornado coroutine返回一种特别类型的异常,叫Return。Coroutine捕获这个异常而且把它当成一个返回值。在Python 3.3版本以上,语句return response.body达到同一的结果。

tornado 学习笔记4 异步以及非阻塞的I/O的更多相关文章

  1. Node.js学习笔记(六) --- Nodejs 的非阻塞 I/O、 异步、 事件驱动

    1. Nodejs 的单线程 非阻塞 I/O 事件驱动在 Java. PHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程.而每个线程需要耗费大约 2MB 内存.也就是说,理论 ...

  2. Tornado用户指引(一)-----------异步和非阻塞I/O

    摘要:异步和非阻塞I/O实时WEB的特性是经常需要为每个用户端维持一个长时间存活但是大部分时候空闲的连接.在传统的同步式web服务器中,这主要通过为每个用户创建一个线程来实现,这样的代价是十分昂贵的. ...

  3. 关于并发,异步,非阻塞(python)疑惑的一些资料解答

    从iterable/iterator到generator到coroutine理解python的迭代器: http://python.jobbole.com/81916/理解python的生成器: ht ...

  4. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  5. tornado 学习笔记1 引言

    从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...

  6. Tornado学习笔记(一) helloword/多进程/启动参数

    前言 当你觉得你过得很舒服的时候,你肯定没有在进步.所以我想学习新的东西,然后选择了Tornado.因为我觉得Tornado更匹配目前的我的综合素质. Tornado学习笔记系列主要参考<int ...

  7. 通俗讲解 异步,非阻塞和 IO 复用

    1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...

  8. 转:IO模型-- 同步和阻塞,异步和非阻塞的区别

    源地址 http://hi.baidu.com/deep_pro/item/db0c581af1c1f17e7b5f2534 这些词之间的区别难倒了很多人,还有什么同步阻塞, 同步非阻塞, 异步阻塞, ...

  9. Git学习笔记(二) · 非典型性程序猿

    远程库的使用 前面说到的都是git在本地的操作,那么实际协作开发过程中我们肯定是要有一个远程版本库作为项目的核心版本库,也就是投入生产使用的版本.这里我们以 Github为例.Github是一个开放的 ...

随机推荐

  1. Chrome Crx 插件下载

    扯蛋的GFW屏蔽了google域导致下载Chrome插件加载失败,本人想收集以些chrome的Crx插件,可供直接下载 XMarks - 在不同电脑不同浏览器之间同步书签 下载地址:   http:/ ...

  2. Object.create 函数 (JavaScript)

    创建一个具有指定原型且可选择性地包含指定属性的对象. 语法 Object.create(prototype, descriptors) 参数 prototype 必需.  要用作原型的对象.  可以为 ...

  3. 攻城狮在路上(壹) Hibernate(十一)--- 映射实体关联关系

    本文以Customer和Address类的关系为例说明一对一关联映射:以Category和Item类的关系说明多对多关联关系.一.映射一对一关联: 分两种情况:按照外键映射和按照主键映射.这两种方式的 ...

  4. HP SAN Switch光纖交換機命令行畫zone

    有時候我們無法登陸網頁交互界面去操縱交換機,如下提供了命令行方式從交換機劃zone 1.創建別名 alicreate "SummaryDB_N", "211,14; 21 ...

  5. 在ASP.NET Core 1.0中如何发送邮件

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:目前.NET Core 1.0中并没有提供SMTP相关的类库,那么要如何从ASP.NE ...

  6. 咱就入个门之NHibernate映射文件配置(二)

    上一篇主要介绍了NHibernate映射文件的基础配置,这篇我们介绍下NHibernate的一对多及多对一配置(文中我直接使用双向关联,即一和多两端都配置,开发中可以只使用一端),同时略带介绍下NHi ...

  7. 信号通讯编程,王明学learn

    信号通讯编程 在Linux系统中,信号(signal)同样也是最为古老的进程间通信机制. 一.信号类型 Linux系统支持的所有信号均定义在/usr/include/asm/signal.h(展示), ...

  8. 链接器工具错误 LNK2026 XXX模块对于 SAFESEH 映像是不安全的

    解决方法: 1.打开该项目的"属性页"对话框. 2.单击"链接器"文件夹. 3.单击"命令行"属性页. 4.将 /SAFESEH:NO 键入 ...

  9. APP交互

    交互设计基本功!5个值得学习的APP交互方式http://www.uisdc.com/5-interactive-design-worth-learning 移动App交互设计10大趋势–你用到了吗? ...

  10. java 日历代码实现

    System.out.println("请输入日期(按照格式:2030-3-10):"); //在控制台输入 //String str="2016-9-26"; ...