Tornado 高并发源码分析之五--- IOLoop 对象
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 对象的更多相关文章
- Tornado 高并发源码分析之三--- Application 对象
Application 对象主要工作: 服务器启动时: 1.在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象 服务器运行时: 2.在请求到来,将 ...
- Tornado 高并发源码分析之四--- HTTPServer 与 TCPServer 对象
主要工作: 服务器启动的时候做的事: 1.把包含了各种配置信息的 application 对象封装到了 HttpServer 对象的 request_callback 字段中,等待被调用 2.TCPS ...
- Tornado 高并发源码分析之二---Tornado启动和请求处理流程
Tornado 服务器启动流程 因为Tornado 里使用了很多传类的方式,也就是delegate,之所以要这么做,其实和 iOS 开发那样,也很多的 delegate, 如此来实现高度解耦,但是比较 ...
- Tornado 高并发源码分析之一---启动一个web服务
前言: 启动一个tornado 服务器基本代码 class HomeHandler(tornado.web.RequestHandler): #创建 RequesHandler 对象,处理接收到的 h ...
- Tornado 高并发源码分析之六---异步编程的几种实现方式
方式一:通过线程池或者进程池 导入库futures是python3自带的库,如果是python2,需要pip安装future这个库 备注:进程池和线程池写法相同 from concurrent.fut ...
- ViewGroup事件分发源码分析
1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...
- Spring AOP 源码分析 - 创建代理对象
1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...
- Flask框架 (四)—— 请求上下文源码分析、g对象、第三方插件(flask_session、flask_script、wtforms)、信号
Flask框架 (四)—— 请求上下文源码分析.g对象.第三方插件(flask_session.flask_script.wtforms).信号 目录 请求上下文源码分析.g对象.第三方插件(flas ...
- JVM源码分析之Java对象头实现
原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Java对象头实现 HotSpot虚拟机中,对象在内存中的布局分为三 ...
随机推荐
- LeetCode OJ:Find Peak Element(寻找峰值元素)
A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...
- SpringCloud教程 | 第十一篇: docker部署spring cloud项目
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://blog.csdn.net/forezp. http://blog.csdn.net/forezp/art ...
- h5启动原生APP总结
许久没有写博客了,最近有个H5启动APP原生页面的需求,中间遇上一些坑,看了些网上的实现方案,特意来总结下 一.需要判断客户端的平台以及是否在微信浏览器中访问 1.客户端判断 在启动APP时,Andr ...
- H264的start code是什么?
H.264起始码 在网络传输h264数据时,一个UDP包就是一个NALU,解码器可以很方便的检测出NAL分界和解码.但是如果编码数据存储为一个文件,原来的解码器将无法从数据流中分别出每个NAL的起始位 ...
- js 获取 本周、上周、本月、上月、本季度、上季度的开始结束日期
js 获取 本周.上周.本月.上月.本季度.上季度的开始结束日期 /** * 获取本周.本季度.本月.上月的开始日期.结束日期 */ var now = new Date(); //当前日期 va ...
- 【转】IUSR和IIS_IUSRS
转自:http://blog.chinaunix.net/uid-20344928-id-3306130.html 概述 在早期的IIS版本中,随着IIS的安装,系统会创建一个IUSR_Mac ...
- [CF662C]Binary Table
luogu 题意 你有一个\(n*m\)的\(01\)矩阵.你可以把任意一行或者一列的\(01\)取反.求矩阵中最少的\(1\)的数量. \(n\le20,m\le10^5\) sol 很自然地有一个 ...
- c# 统计运行时间
long startTime = Environment.TickCount; long endTime = Environment.TickCount; long totalTime = endTi ...
- 洛谷 P1227 [JSOI2008]完美的对称
传送门 题目大意:求一些点集的公共对称中心 题解:对称中心是可以确定的,再判断. 代码: #include<iostream> #include<cstdio> #includ ...
- C#网络编程(接收文件) - Part.5
这篇文章将完成 Part.4 中剩余的部分,它们本来是一篇完整的文章,但是因为上一篇比较长,合并起来页数太多,浏览起来可能会比较不方便,我就将它拆为两篇了,本文便是它的后半部分.我们继续进行上一篇没有 ...