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. axios 讲解 和vue搭建使用

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

  2. CSS: Flexbox

    Use flexbox to create a responsive website, containing a flexible navigation bar and flexible conten ...

  3. 浅析C#中抽象类和接口的区别

    声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况.不能创建abstract 类的实例.然 ...

  4. Python探索记(18)——文件File

    # @Time : 2017/7/8 21:10 # @Author : 原创作者:谷哥的小弟 # @Site : 博客地址:http://blog.csdn.net/lfdfhl # @DESC : ...

  5. Activity的生命周期,BACK键和HOME对生命周期的影响

    下面这张图详细的描述了Activity的整个生命周期: 直接上代码,注意看注释: [java] view plaincopy public class HelloActivity extends Ac ...

  6. 请求URL中有body怎么使用jmeter进行接口测试

    业务场景: 微信内免费领取激活码 1.点击“免费领取”按钮调取的接口 2.URL如下 https://yxyapi2.drcuiyutao.com/yxy-api-gateway/api/json/v ...

  7. sublime上配置markdown

    等等等等 简书一个不错的教程:Sublime Text3的Markdown配置 补充说明:第一步可以直接找 Tools-->install package control. ^.^ ...

  8. SVN客户端与服务器端搭建操作

    一.客户端的安装 1.点击安装程序 2.修改svn安装位置 3.开始安装 4.客户端安装成功 5.回到左面  右键出现svn检出 tortoiSVN  表示安装成功 Myeclipse svn插件安装 ...

  9. Django-rest-framework多条件查询/分页/多表Json

    http://www.mamicode.com/info-detail-1648765.html

  10. docker 命令记录

    从 Docker 镜像仓库获取镜像的命令是 docker pull.其命令格式为: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 具体的选项 ...