• 摘要:异步和非阻塞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. 深度优先搜索算法(Depth-First-Search,DFS)

    深度优先搜索算法的概念 与广度优先搜索算法不同,深度优先搜索算法类似与树的先序遍历.这种搜索算法所遵循的搜索策略是尽可能"深"地搜索一个图.它的基本思想如下:首先访问图中某一个起始 ...

  2. as3.2版本中中jar生成方法

    lintOptions { abortOnError false } task makeJar(type: Copy) { //删除存在的 delete 'build/libs/myjar.jar' ...

  3. linux 系统开机自启执行 操作的配置

    1 linux 服务注册 service文件 在service文件中设置变量和环境变量 [Unit] Description= #服务描述 After=syslog.target #服务启动依赖 [S ...

  4. Android之自定义View以及画一个时钟

    https://www.2cto.com/kf/201509/443112.html 概述: 当Android自带的View满足不了开发者时,自定义View就发挥了很好的作用.建立一个自定义View, ...

  5. ping外网

    /** * @author suncat * @category 判断是否有外网连接(普通方法不能判断外网的网络是否连接,比如连接上局域网) * @return */ public static fi ...

  6. MSSQL 备份与恢复

    建立维护计划,需启用<SQL Server 代理>服务 建立三个子作业: 1. 按周进行的全备份,每周日零点执行 2. 按天进行的差异备份,每天中午12点执行 3. 按小时执行的事务日志备 ...

  7. x64 QWORD Xor shellcode encoder

    #!/usr/bin/env python #Filename: Xor_QWORD_x64.py #coding=utf-8 import re import sys import random i ...

  8. HDU 3420 -- Bus Fair ACM

    Bus Fair Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  9. css3 box-shadow属性 鼠标移动添加阴影效果

    text-shadow是给文本添加阴影效果,box-shadow是给元素块添加周边阴影效果. 基本语法:{box-shadow:[inset] x-offset  y-offset  blur-rad ...

  10. Steeltoe

    谈谈Circuit Breaker在.NET Core中的简单应用 http://www.cnblogs.com/catcher1994/p/8975192.html 前言 由于微服务的盛行,不少公司 ...