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虚拟机中,对象在内存中的布局分为三 ...
随机推荐
- Oracle11g数据库监听配置
(转自:http://blog.sina.com.cn/s/blog_6908928501018057.html) 经验告诉我:最好把数据库的SID和数据库全局名称分开,免得配置时混了,如果要配置服务 ...
- 【第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛-L】用来作弊的药水
链接:https://www.nowcoder.com/acm/contest/90/L来源:牛客网 输入x,a,y,b,(1<=x,a,y,b<=10^9)判断x^a是否等于y^b 前面 ...
- js 设置日期函数
前三十天: var now = new Date(); var prev = now.setDate( now.getDate() - 30 ) vm.sDate = comm.getFormatDa ...
- 记录下jplayer的简单demo
jplay一个播放器的工具包,依赖于jquery或者zepto,有zepto所以相当于是PC和移动都支持. 它的官方文档为:http://www.jplayer.cn/ 同时也推出的react的支持包 ...
- spring import jar中的bean配置文件
在spring中import resource file,有两种情况:classes目录和jar包 如果资源文件在classes目录: <import resource="classp ...
- v-if和v-show的区别
v-if 是“真实”的条件渲染,因为它会确保条件块(conditional block)在切换的过程中,完整地销毁(destroy)和重新创建(re-create)条件块内的事件监听器和子组件. v- ...
- VC++6.0/MFC 自定义edit 限制输入内容 响应复制粘贴全选剪切的功能
Ctrl组合键ASCII码 ^Z代表Ctrl+z ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符0(00) ...
- sql_自连接,181,182,196,197
181. Employees Earning More Than Their Managers https://leetcode.com/problems/employees-earning-more ...
- python加密之hashlib
1.强大的hashlib,提供了用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 2.hmac模块实 ...
- CH1801 括号画家(栈模拟)
描述 Candela是一名漫画家,她有一个奇特的爱好,就是在纸上画括号.这一天,刚刚起床的Candela画了一排括号序列,其中包含小括号( ).中括号[ ]和大括号{ },总长度为N.这排随意绘制的括 ...