IOLoop主要工作
1、将TCPServer 注册到 IOLoop 的事件记到 _handlers 字段,同时注册 READ 和 ERROR 事件到 epoll
2、IOLoop 启动一个大循环,负责轮询epoll中是否已经有就绪的事件,如果有就执行对应的回调
 
以下为源码分析,省略部分源码,只取主要部分
 class Configurable(object):
"""根据子类的配置,来创建一个对象,也就是说,继承自Configurable的子类,可以自己配置产生不同的类,并且每个类都会执行initialize方法
__impl_class = None
__impl_kwargs = None def __new__(cls, **kwargs):
base = cls.configurable_base()
args = {}
if cls is base:
impl = cls.configured_class()
if base.__impl_kwargs:
args.update(base.__impl_kwargs)
else:
impl = cls
args.update(kwargs)
instance = super(Configurable, cls).__new__(impl)
instance.initialize(**args) #执行initialize方法
return instance

Configurable

 class IOLoop(Configurable):
" 一个大循环,自动根据当前的系统,是 linux 2.5以上选择epoll, mac 选择kqueue, 其他选择select".
@staticmethod
def instance(): #创建一个全局的 IOLoop 单例
if not hasattr(IOLoop, "_instance"):
with IOLoop._instance_lock:
if not hasattr(IOLoop, "_instance"):
IOLoop._instance = IOLoop()
return IOLoop._instance @classmethod 配置
def configurable_base(cls):
return IOLoop @classmethod
def configurable_default(cls): #根据系统,配置使用epoll还是 kqueue
if hasattr(select, "epoll"):
from tornado.platform.epoll import EPollIOLoop
return EPollIOLoop
if hasattr(select, "kqueue"):
# Python 2.6+ on BSD or Mac
from tornado.platform.kqueue import KQueueIOLoop
return KQueueIOLoop
from tornado.platform.select import SelectIOLoop
return SelectIOLoop

IOLoop

 class PollIOLoop(IOLoop):
"继承自IOLoop, 就是IOLoop 在根据系统选择的时候,真正创建的类对象" def add_handler(self, fd, handler, events):
fd, obj = self.split_fd(fd)
self._handlers[fd] = (obj, stack_context.wrap(handler)) #将socket对象的句柄fd作为key, 回调函数handler作为值,添加到 _handlers 字段中, 其实这里的函数就是在TCPServer 启动时添加的 _handle_connection 方法
self._impl.register(fd, events | self.ERROR) #向_impl (在linux中是epoll,在mac中是kqueue,2.5版本一下的linux中是select)中注册对应句柄fd 的事件(其实就是READ和error事件) def start(self): try:
while True: #启动IOLoop 大循环, 这是一个无限循环 with self._callback_lock: #如果有上一个循环没有执行完毕的函数,继续拿出来执行
callbacks = self._callbacks
self._callbacks = [] try:
event_pairs = self._impl.poll(poll_timeout) #从epoll中取出已经就绪的事件
except Exception as e:
if errno_from_exception(e) == errno.EINTR:
continue
else:
raise self._events.update(event_pairs) #将事件更新到 _events dict中
while self._events:
fd, events = self._events.popitem()
try:
fd_obj, handler_func = self._handlers[fd] #从刚开始添加事件到_handler里面取出对应的回调函数
handler_func(fd_obj, events) #执行回调函数, 其实也就是执行TCPServer中的self._handle_connection 方法
except (OSError, IOError) as e:
self.handle_callback_exception(self._handlers.get(fd))
except Exception:
self.handle_callback_exception(self._handlers.get(fd))
fd_obj = handler_func = None #清空,准备进入下一次循环 finally:
ignal.set_wakeup_fd(old_wakeup_fd)

PollIOLoop

Tornado 高并发源码分析之五--- IOLoop 对象的更多相关文章

  1. Tornado 高并发源码分析之三--- Application 对象

    Application 对象主要工作: 服务器启动时: 1.在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象   服务器运行时: 2.在请求到来,将 ...

  2. Tornado 高并发源码分析之四--- HTTPServer 与 TCPServer 对象

    主要工作: 服务器启动的时候做的事: 1.把包含了各种配置信息的 application 对象封装到了 HttpServer 对象的 request_callback 字段中,等待被调用 2.TCPS ...

  3. Tornado 高并发源码分析之二---Tornado启动和请求处理流程

    Tornado 服务器启动流程 因为Tornado 里使用了很多传类的方式,也就是delegate,之所以要这么做,其实和 iOS 开发那样,也很多的 delegate, 如此来实现高度解耦,但是比较 ...

  4. Tornado 高并发源码分析之一---启动一个web服务

    前言: 启动一个tornado 服务器基本代码 class HomeHandler(tornado.web.RequestHandler): #创建 RequesHandler 对象,处理接收到的 h ...

  5. Tornado 高并发源码分析之六---异步编程的几种实现方式

    方式一:通过线程池或者进程池 导入库futures是python3自带的库,如果是python2,需要pip安装future这个库 备注:进程池和线程池写法相同 from concurrent.fut ...

  6. ViewGroup事件分发源码分析

    1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...

  7. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  8. Flask框架 (四)—— 请求上下文源码分析、g对象、第三方插件(flask_session、flask_script、wtforms)、信号

    Flask框架 (四)—— 请求上下文源码分析.g对象.第三方插件(flask_session.flask_script.wtforms).信号 目录 请求上下文源码分析.g对象.第三方插件(flas ...

  9. JVM源码分析之Java对象头实现

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Java对象头实现 HotSpot虚拟机中,对象在内存中的布局分为三 ...

随机推荐

  1. CSS:Tutorial four

    1.CSS Tables To specify table borders in CSS, use the border property. The example below specifies a ...

  2. Agilent RF fundamentals (2)- fundamental units of RF

    1Amplitude AM调制 2 Frequency FM调制 3Phase Phase 调制 复合调制 三者关系:

  3. IOS对存放对象的数组排序

    我们开发的每个程序都会使用到一些数据,而这些数据一般被封装在一个自定义的类中.例如一个音乐程序可能会有一个Song类,聊天程序则又一个 Friend类,点菜程序会有一个Recipe类等.有时候我们希望 ...

  4. Chrome 开发者控制台使用技巧

    Chrome 有内置的开发者工具.它拥有丰富的特性,比如元素(Elements).网络(Network)和安全(Security).今天,我们主要关注一下 JavaScript 控制台. 当我最初写代 ...

  5. 如何在JM8.6编码端提取QDCT?

    毫无疑问,编码端的QDCT和解码端的QDCT完全相同,下面从编码端提取QDCT. 为简便起见,仅提取第一帧第一个宏块第一个4*4块的QDCT.JM8.6编码器最核心的编码函数是encode_one_m ...

  6. Build ios app with Delphi Xe4. Lazy Social Talker ready for sale.

    Yes, it is build with Delphi XE4. try it. now. What is  Lazy Social  Talker? Lazy Social Talker is a ...

  7. 学习Java有没有什么捷径?

    很多网友咨询学习Java有没有什么捷径,我说“ 无他,唯手熟尔 ”.但是愿意将一些经验写出来,以便后来者少走弯路,帮助别人是最大的快乐嘛! 要想学好Java,首先要知道Java的大致分类. 我们知道, ...

  8. H5打字机特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. browser-sync 服务器使用

    1. 安装 npm install browser-sync or yarn add browser-sync 2. 使用(集成gulp) 备注: gulp 安装使用此处不介绍 默认的端口是3000, ...

  10. ORA-12154,TNS错误解决办法