ioloop 即io事件处理轮询
本文就从下面这个 Tornado 官方的例子程序开始:
|
|
以 tornado.ioloop.IOLoop().current().start()
为起点,切入 ioloop 的处理过程。首先程序来到类 IOLoop
的 current
方法:
|
|
IOLoop
的父类为 Configurable
,其使用 new() 方法进行初始化(new()方法在init()方法之前被调用,它可以决定一个类是否使用init()方法进行初始化)。
|
|
Configurable
类中的 new() 方法中,根据具体实现类(子类)继承实现的几个重要方法来完成本身的初始化,new() 方法其实是一个工厂方法。其中,cls.configured_class()
方法获取本次运行环境下的使用的轮询方式(比如epoll/kqueue/select):
|
|
测试环境为centos,返回值为 EPollIOLoop
。我们来看下其实现:
|
|
EPollIOLoop
从 PollIOLoop
继承而来,而且impl默认值为 select.epoll()。文章最开始的例子中的 tornado.ioloop.IOLoop().current().start()
其实就是类 PollIOLoop
的 start()
方法,我们看下该类的 initialize()
和 start()
方法:
|
|
initialize()
方法中做了实际的初始化工作,后续再详细展开细节的研究,暂时略过。
start()
方法中重点看下 event_pairs = self._impl.poll(poll_timeout)
,其作用就是使 epoll 进入等待状态。当有IO任务处于就绪状态时,该方法返回 event_pairs
。self._events.update(event_pairs)
将就绪任务记录到 self._events
,根据fd从 self._handlers
中对应取出 handler_func 处理函数,并且将该函数作为就绪事件的回调函数,执行真正的IO处理工作。