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. SQL Server中的联合主键、聚集索引、非聚集索引

    我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...

  2. LeetCode OJ:Insertion Sort List (插入排序链表)

    Sort a linked list using insertion sort. 用插入排序来排序一个list,额, 我写的好麻烦啊, debug了好久,至少提交了5次...写吐了快,先贴代码,写的也 ...

  3. SEH:结构化异常处理 学习

    SEH:结构化异常处理 结构化异常处理机制提供了一个操作系统,用于优化结构的方案,为客户提供更强大的程序执行环境.试想一下,你写程序不用考虑内存访问错误,那里是空指针错误,一直在按照程序的逻辑结构来写 ...

  4. SlowHTTPTest-慢速DoS攻击

    Slowhttptest是一个依赖于实际HTTP协议的Slow HTTP DoS攻击工具,它的设计原理是要求服务器所有请求被完全接收后再进行处理. SlowHTTPTest是一款对服务器进行慢攻击的测 ...

  5. VS2013 快捷方式

    1.查找空行:  使用正则表达式 ^\s\S*$\n

  6. 【经典】Noip动态规划

    一.线性动态规划 最长严格上升子序列 #include<iostream> #include<cstdio> using namespace std; int n,ans; ] ...

  7. noip济南清北冲刺班DAY2

    题解: 贪心+dp 30% N<=5  5!枚举一下 20%  高度没有的时候,高度花费就不存在了,将ci排序, 从小到大挨个跳.另外,20% 准备跳楼没有花费,那么跳 楼的高度一定是从小到大, ...

  8. 【LeetCode】129. Sum Root to Leaf Numbers

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...

  9. Markdown编辑器推荐与语法教程--图片版

    请参考Markdown编辑器推荐与语法教程--展示版或者Markdown编辑器推荐与语法教程--展示版看具体效果,当然,大家也可以下载Mou亲自体验一把 End

  10. Oracle查询脚本优化

    发现生产环境的Oracle数据库cpu使用率上升超过70%,其中一条查询语句达到每秒调用40多次.现在我们来观摩下该语句: select t.id,t.level,t.policy, t.type,t ...