什么是Tornado IOLoop,以及Tornado的工作流程?

30
我想了解Tornado的内部工作流程,看过这篇文章,很好,但有些地方我无法理解。
在ioloop.py中,有这样一个函数。
def add_handler(self, fd, handler, events):
    """Registers the given handler to receive the given events for fd."""
    self._handlers[fd] = handler
    self._impl.register(fd, events | self.ERROR)

这是什么意思?每个请求都会触发add_handler,还是只在初始化时触发一次?

每个socket连接都会生成一个文件描述符,还是只生成一次?

ioloop和iostream之间的关系是什么?

httpserver如何与ioloop和iostream配合工作?

是否有工作流程图,以便清晰地查看?

对不起,我有些困惑。

任何链接、建议或提示都很有帮助。非常感谢 :)

1个回答

31

我会按照顺序回答你的问题:

  • 这里的_impl是可用的套接字轮询机制,Linux上是epoll,Windows上是select。因此,self._impl.register(fd, events | self.ERROR)将“等待某些事件”的请求传递给底层操作系统,还特别包括错误事件。

    当运行HTTPServer时,将使用IOLoop.add_handler()来注册要接受连接的套接字。当接受连接时,它们将生成更多的通信套接字,这些套接字可能也会通过IOStream添加事件处理程序,这也可能调用add_handler()。因此,新的处理程序将在开始时和在接收到连接时加入。

  • 是的,每个新的套接字连接都有唯一的文件描述符。原始的监听HTTPServer的套接字应该保留其文件描述符。文件描述符由操作系统提供。

  • IOLoop处理与套接字相关的事件,例如它们是否有可读数据、它们是否可以写入以及是否发生了错误。通过使用诸如epollselect之类的操作系统服务,它可以高效地完成此操作。

    IOStream处理在单个连接上的流数据传输,并使用IOLoop以异步方式完成此操作。例如,IOStream可以读取所有可用的数据,然后使用IOLoop.add_handler()等待更多数据可用。

  • listen()中,HTTPServer创建一个套接字来使用IOLoop监听连接。当获取到连接时,它使用socket.accept()创建一个新的套接字,然后使用一个新的HTTPConnection与客户端进行通信。

    HTTPConnection 使用 IOStream 来与客户端传输数据。这个 IOStream 使用 IOLoop 来异步非阻塞地完成该操作。可以同时激活许多IOStreamHTTPConnection 对象,它们全部使用同一个 IOLoop 进行操作。

  • 希望这些回答能解决你的一些问题。我不知道有没有好的结构图,但对于其他的 web 服务器来说,总体思路应该是相似的,所以也许会有一些好的信息可供参考。你提供的那篇深度文章看起来很有用,如果你理解得足够多,我建议再去读一遍 :)


它们将生成更多的通信套接字,这些套接字是Linux内部套接字(Unix域套接字)吗? - limboy
1
@Izyy 我认为它们是“互联网套接字”(在Python中的socket.AF_INET类型)。维基百科有一些很好的信息。主侦听套接字只具有接收地址+端口,但每个新的通信套接字都将具有本地和远程地址+端口,使其能够唯一应用于每个客户端连接,即使它们在服务器上具有相同的本地地址。不过,我不确定确切的实现细节 :). - mesilliac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接