美文网首页python进阶tornado
Tornado入门(二)【异步和阻塞IO】

Tornado入门(二)【异步和阻塞IO】

作者: nummycode | 来源:发表于2017-09-30 11:17 被阅读68次

实时Web应用通常针对每个用户创建持久连接,对于传统的同步服务器,这意味着需要给每个用户单独创建一个线程,这样做的代价非常高。

为了减少并发连接的消耗,Tornado采用了单线程事件循环模型,这也就意味着所有的应用代码都必须是异步非阻塞的,因为一次只能有一个活跃的操作。

异步和非阻塞其实紧密关联,通常它们可以互换,但是它们并不是同一个概念。

阻塞

当函数需要等待某件事情的发生并返回结果时,它就处于阻塞状态。一个函数可能因为很多原因阻塞,网络IO,磁盘IO, 互锁等等。实际上,每个函数都会阻塞,当它运行并占用CPU的时候, 都会占用那么一点时间。

函数有些情况可能会阻塞,有些情况又不会阻塞。例如,tornado.httpclient在采用默认配置的情况下,解析DNS的时候会阻塞,但其它网络访问并不会阻塞。在Tornado中,我们谈到的阻塞一般是针对网络IO,而忽略其它的阻塞。

异步

异步函数在结束之前就返回了,它通常在后台触发一些任务,等执行完之后再调用某些操作。有很多异步接口的实现:

  • 回调函数
  • 返回一个占位符(Future, Promise,Defered)
  • 传送给队列
  • 信号机制

不管采用哪种异步方式,异步函数与调用者的交互都不是同步的。

示例

下面是一个简单的同步函数:

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,因为它有两个优点:

  • 错误处理更为一致,因为Future.result可以抛出异常。
  • Future在协程中使用非常方便。

协程在后面会重点介绍,下面是采用协程方式编写的代码:

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,因为Python2中生成器不允许返回值,为了克服这一点,Tornado协程抛出了一种特殊的异常Return,协程会捕获这个异常,然后将它当做返回值处理,在Python3中,可以直接使用return response.body

相关文章

  • Tornado入门(二)【异步和阻塞IO】

    实时Web应用通常针对每个用户创建持久连接,对于传统的同步服务器,这意味着需要给每个用户单独创建一个线程,这样做的...

  • tornado框架

    1.支持异步非阻塞,底层使用epoll,IO多路复用2.tornado不是基于wsgi,而是基于tornado,运...

  • tornado【5】阻塞与异步概念

    在tornado中,我们谈到的阻塞一般是针对网络IO,而忽略其它的阻塞(磁盘IO, 互锁)。 异步函数在结束之前就...

  • Java IO快速入门

    网络IO实现方式分为BIO(阻塞IO)、线程池伪异步IO、NIO(非阻塞IO)、AIO(异步非阻塞IO); 异步、...

  • Java IO

    Before IO 分为:同步、异步阻塞、非阻塞 同步和异步是目的,阻塞和非阻塞是实现方式。 一个IO操作其实分成...

  • IO模型

    原文参考链接 四种状态 同步 异步 阻塞 非阻塞 IO分类 同步阻塞IO 同步非阻塞IO 异步非阻塞IO注意: 没...

  • 阻塞非阻塞 同步异步 IO模型及其应用 NIO实现原理

    1.同步异步概念 2.阻塞非阻塞概念 3.常见I/O模型:同步阻塞IO,同步非阻塞IO,异步阻塞IO,异步非阻塞I...

  • Reactor模式

    关键词:Reactor模式 IO NIO 阻塞 异步 阻塞/异步概念:读网络教科书 Java NIO和IO区...

  • UNIX 的5种IO模型介绍

    IO模型同步、异步、阻塞、非阻塞socket阻塞与非阻塞,同步与异步 同步和异步 同步/异步主要针对C端-同步就像...

  • 同步、异步阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻...

网友评论

    本文标题:Tornado入门(二)【异步和阻塞IO】

    本文链接:https://www.haomeiwen.com/subject/lpygextx.html