【问题标题】:How do you understand the ioloop in tornado?你如何理解龙卷风中的 ioloop?
【发布时间】:2018-07-20 03:15:27
【问题描述】:

我正在寻找一种理解ioloop in tornado的方法,因为我多次阅读官方文档,但无法理解。具体来说,它为什么存在。

from tornado.concurrent import Future
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop
def async_fetch_future():
    http_client = AsyncHTTPClient()
    future = Future()
    fetch_future = http_client.fetch(
        "http://mock.kite.com/text")
    fetch_future.add_done_callback(
        lambda f: future.set_result(f.result()))
    return future

response = IOLoop.current().run_sync(async_fetch_future) 
# why get current IO of this thread? display IO, hard drive IO, or network IO? 
print response.body

我知道什么是 IO,输入和输出,例如读取硬盘驱动器,在屏幕上显示图形,获取键盘输入。 根据定义,IOLoop.current() 返回此线程的当前 io 循环。

我的笔记本电脑上有很多 IO 设备运行这个 python 代码。这个IOLoop.current() 返回哪个 IO?我从来没有听说过javascript nodejs中的IO循环。

此外,如果我只想进行数据库查询、读取文件,我为什么要关心这个低级的事情?

【问题讨论】:

  • Tornado 的 IOLoop 与您笔记本电脑的设备无关。而是对打开的套接字和文件对象进行异步读写操作。
  • 您必须阅读 Linux 中的 select 函数才能更好地了解异步、非阻塞 I/O。所以,Tornado 的 IOLoop 只是为底层操作系统的 async selectpoll 等函数提供了一个 API。请参阅此页面 - pymotw.com/3/select。该页面上的代码示例是关于在套接字上执行异步 I/O。因此,Tornado 的 IOLoop 已经处理了所有这些事情,并使用户更轻松。

标签: python tornado


【解决方案1】:

我从未听说过 javascript nodejs 中的 IO 循环。

在 node.js 中,等效的概念是event loop。节点事件循环大部分是不可见的,因为所有程序都使用它——它是在你的回调之间运行的。

在 Python 中,大多数程序不使用事件循环,所以当你想要一个时,你必须自己运行它。这可以是 Tornado IOLoop、Twisted Reactor 或 asyncio 事件循环(所有这些都是特定类型的事件循环)。

Tornado 的 IOLoop 名称可能令人困惑——它不直接执行任何 IO。相反,它协调程序中可能发生的所有不同的 IO(主要是网络 IO)。它可以帮助您将其视为“事件循环”或“回调运行器”。

【讨论】:

    【解决方案2】:

    不如说是IOLoop,或许EventLoop更容易理解。

    IOLoop.current() 并不真正返回一个 IO 设备,而只是一个纯 python 事件循环,它与asyncio.get_event_loop()nodejs 中的底层事件循环基本相同。

    您需要事件循环来执行数据库查询的原因是您正在使用事件驱动的结构来执行数据库查询(在您的示例中,您正在执行 http 请求)。

    大多数时候你不需要关心这个低级结构。相反,您只需要使用 async&await 关键字。

    假设有一个支持异步数据库访问的库:

    async def get_user(user_id):
        user = await async_cursor.execute("select * from user where user_id = %s" % user_id)
        return user
    

    那么你只需要在你的处理程序中使用这个函数:

    class YourHandler(tornado.web.RequestHandler):
    
        async def get():
            user = await get_user(self.get_cookie("user_id"))
            if user is None:
                return self.finish("No such user")
            return self.finish("Your are %s" % user.user_name)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多