• 摘要:异步和非阻塞I/O实时WEB的特性是经常需要为每个用户端维持一个长时间存活但是大部分时候空闲的连接。在传统的同步式web服务器中,这主要通过为每个用户创建一个线程来实现,这样的代价是十分昂贵的。为了最大限度地减少并发成本,Tornado使用单线程的事件循环机制(linux中是基于epoll的).这就意味着所有的应用代码都应该是异步或非阻塞的,因为同时只能有一个操作是活动的。尽管异步和非阻塞这2个术语是密切相关的,并且通常可以互换使用,但并不完全相同。阻塞当一个函数在等待某些事
    • 异步和非阻塞I/O

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

      为了最大限度地减少并发成本,Tornado使用单线程的事件循环机制(linux中是基于epoll的).这就意味着所有的应用代码都应该是异步或非阻塞的,因为同时只能有一个操作是活动的。

      尽管异步和非阻塞这2个术语是密切相关的,并且通常可以互换使用,但并不完全相同。

      阻塞
      当一个函数在等待某些事件的时候就会阻塞。一个函数阻塞的原因有很多:网络I/O,磁盘I/O,锁等等。
      实际上,所有的函数在使用CPU的时候,都多多少少的会阻塞,至少会有一点点。
      下面有一个极端的例子演示了为什么CPU阻塞比其他类型的阻塞还要严重。
      密码哈希函数比如bcrypt,被设计为要使用数百ms的CPU时间,远远大于通常的网络或磁盘访问。

      一个函数可以在某些方面阻塞,也可以在某些方面非阻塞。
      比如,在默认配置下,tornado.httpclient会在DNS解析时阻塞但是不会在其他网络访问时阻塞(为了缓解这种状况,可以使用ThreadResolver和tornado.curl_httpclient
      它们是通过合适的配置用libcurl来构建的)
      在tornado的背景中,我们一般只讨论网络I/O下的阻塞,尽管其它类型的阻塞也被最小化了。

      异步
      一个异步函数在它完成之前返回,在应用程序触发一些未来的动作之前,需要在后台做一些工作。这与同步函数正好相反,同步函数在返回之前把所有要做的事件都做完。
      有许多类型的异步接口:
      1.回调函数参数
      2.返回一个占位符(Future,Promise,Deferred)
      3.发送到队列
      4.回调函数注册(比如POSIX标准的信号)
      不管何种类型的异步接口,调用者都采用不同方式使用这些异步接口。把同步函数转换为异步函数需要采用一定的方法,这种转换对调用者是透明的。(一些系统比如gevent使用
      轻量级的线程来提供与异步系统相似的性能,但是它们并不是真正地异步)

      举例
      下面是一个同步函数的例子:
      from tornado.httpclient import HTTPClient

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

      然后是一个通过回调函数将同样功能的函数变为异步的例子:
      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无条件地建议在实际编程中使用Future,因为有以下2点好处:
      1.使错误处理更加一致,因为Future.result方法可以简单地抛出一个异常
      2.Future很好地使用了coroutines.Coroutines将在下一节进行更深的讨论。
      下面是一个coroutine版本的异步函数,与最开始的同步函数十分相似:
      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)语句是一个包装在python2和python3.2里,因为python的这些版本不支持将生成器函数作为返回值。
      为了克服这个,Tornado coroutines抛出一个特殊种类的异常,称为Return. 
      coroutine捕获这个异常并将它当作一个返回值。
      在Python3.3和之后的版本里面,使用"return response.body"的效果是一样的。

Tornado用户指引(一)-----------异步和非阻塞I/O的更多相关文章

  1. tornado 学习笔记4 异步以及非阻塞的I/O

    Read-time(实时)的网站需要针对每个用户保持长时间的连接.在传统的同步网站服务中,通常针对每个用户开启来一个线程来实现,但是这样做非常昂贵. 为了使并发连接的成本最小化,Tornada使用单个 ...

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

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

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

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

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

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

  5. tornado异步请求非阻塞

    前言也许有同学很迷惑:tornado不是标榜异步非阻塞解决10K问题的嘛?但是我却发现不是torando不好,而是你用错了 比如最近发现一个事情:某网 前言 也许有同学很迷惑:tornado不是标榜异 ...

  6. tornado异步请求非阻塞-乾颐堂

    前言 也许有同学很迷惑:tornado不是标榜异步非阻塞解决10K问题的嘛?但是我却发现不是torando不好,而是你用错了.比如最近发现一个事情:某网站打开页面很慢,服务器cpu/内存都正常.网络状 ...

  7. tornado : 异步、非阻塞

    The terms asynchronous and non-blocking are closely related and are often used interchangeably, but ...

  8. 异步、非阻塞和IO多路复用总结

    Nginx是并发处理框架的代表者,很多后台业务都会放在Nginx容器中运行,以实现高吞吐,而Nginx能够支持高并发也是由于使用了异步非阻塞处理模型,本文将用通俗的话讲解异步.同步.阻塞.非阻塞的区别 ...

  9. tornado用户指引(二)------------tornado协程实现原理和使用(一)

    摘要:Tornado建议使用协程来实现异步调用.协程使用python的yield关键字来继续或者暂停执行,而不用编写大量的callback函数来实现.(在linux基于epoll的异步调用中,我们需要 ...

随机推荐

  1. latex 调整间隔

    转自:http://blog.sina.com.cn/s/blog_4a4927c70100phsb.html,感谢分享! 一.LATEX调整公式与正文间距离,调整空白大小:   调整空白命令: \s ...

  2. idea引入依赖包报错

    今天在更新项目的时候,maven依赖的一个服务一直报错.查了后发现原来是因为缺少依赖包.但是依赖包明明在我本地啊. 又重新下载,依然如故... 搞了半天,发现自己的依赖包类状态都是不可用的.如下图所示 ...

  3. Linux Firefox Adobe Flash Player 安装和更新

    1.下载 Firefox Adobe Flash Player 使用Linux上的火狐浏览器访问如下的下载网址: https://get.adobe.com/flashplayer/ 选择下载 &qu ...

  4. 使用intellij idea搭建MAVEN+SSM(Spring+SpringMVC+MyBatis)框架

    基本概念 使用SSM(Spring,SpringMVC和Mybatis) 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod  ...

  5. leetcode-wildcard matching-ZZ

    http://yucoding.blogspot.com/2013/02/leetcode-question-123-wildcard-matching.html 几个例子: (1) acbdeabd ...

  6. POI 导出excel带小数点的数字格式显示不对解决方法

    最近看到了一个问题就是java导出excel中带小数点的数字显示不对, 比如我想在excel中第一行显示:  3,000.0 但是在excle中导出的格式总是不带小数点 3000(非文本格式),而且也 ...

  7. 初看Mybatis 源码 (三) SQL是怎么执行的

    前面说到Java动态代理,Mybatis通过这种方式实现了我们通过getMapper方式得到的Dao接口,可以直接通过接口的没有实现的方法来执行sql. AuthUserDao mapper = se ...

  8. Elasticsearch 2.x.x版本如何安装bigdesk

    ES插件BigDesk安装 bigdesk支持的最新版本的ES是1.3.0 ... 1.3.x 然而想要在新版本ES上安装(2.x.x),项目中遇到过一些BUG,在ES在最新版本中有修复,所以采用了2 ...

  9. February 20 2017 Week 8 Monday

    Behind every beautiful thing, there's some kind of pain. 美丽背后,必有努力. No pains, no gains, and sometime ...

  10. js 联动实现日期选择,一般用作生日

    实现目标:年月日三个select 输入框,以及一个hidden的input,通过js获取input的值,如果有值切是日期格式,年月日select为input中的时间.否则为空.年默认区间段为1900年 ...