twisted internet.reactor部分 源码分析
twisted.internet.reactor 是进行所有twisted事件循环的地方。
reactor在1个python进程中只能有一个。
在windows下用的是select。linux下epool。mac下是pool,这点和socketserver,tornado的都一样哈()。
源码位于twisted.internet.default._getInstallFunction
try:
if platform.isLinux():
try:
from twisted.internet.epollreactor import install
except ImportError:
from twisted.internet.pollreactor import install
elif platform.getType() == 'posix' and not platform.isMacOSX():
from twisted.internet.pollreactor import install
else:
from twisted.internet.selectreactor import install
except ImportError:
from twisted.internet.selectreactor import install
return install
看SelectReactor
try:
from twisted.internet.win32eventreactor import _ThreadedWin32EventsMixin
except ImportError:
_extraBase = object
else:
_extraBase = _ThreadedWin32EventsMixin
@implementer(IReactorFDSet)
class SelectReactor(posixbase.PosixReactorBase, _extraBase):
"""
A select() based reactor - runs on all POSIX platforms and on Win32. @ivar _reads: A set containing L{FileDescriptor} instances which will be
checked for read events. @ivar _writes: A set containing L{FileDescriptor} instances which will be
checked for writability.
"""
balabala........
主要功能实现在posixbase.PosixReactorBase这个类。然后根据os的不同,混入不同的多线程mixin。
每种Reactor要实现IReactorFDSet的接口。接口定义的是管理 端口状态的方法。比如addReader,addWriter。。还是放代码吧。
class IReactorFDSet(Interface):
"""
Implement me to be able to use L{IFileDescriptor} type resources. This assumes that your main-loop uses UNIX-style numeric file descriptors
(or at least similarly opaque IDs returned from a .fileno() method)
""" def addReader(reader):
"""
I add reader to the set of file descriptors to get read events for. @param reader: An L{IReadDescriptor} provider that will be checked for
read events until it is removed from the reactor with
L{removeReader}. @return: C{None}.
""" def addWriter(writer):
"""
I add writer to the set of file descriptors to get write events for. @param writer: An L{IWriteDescriptor} provider that will be checked for
write events until it is removed from the reactor with
L{removeWriter}. @return: C{None}.
""" def removeReader(reader):
"""
Removes an object previously added with L{addReader}. @return: C{None}.
""" def removeWriter(writer):
"""
Removes an object previously added with L{addWriter}. @return: C{None}.
""" def removeAll():
"""
Remove all readers and writers. Should not remove reactor internal reactor connections (like a waker). @return: A list of L{IReadDescriptor} and L{IWriteDescriptor} providers
which were removed.
""" def getReaders():
"""
Return the list of file descriptors currently monitored for input
events by the reactor. @return: the list of file descriptors monitored for input events.
@rtype: C{list} of C{IReadDescriptor}
""" def getWriters():
"""
Return the list file descriptors currently monitored for output events
by the reactor. @return: the list of file descriptors monitored for output events.
@rtype: C{list} of C{IWriteDescriptor}
"""
没什么奇怪的地方。。
所以就不看这边了。这地方太熟了。除去了多线程的Mixin和端口reader,writer的接口,剩下的就是reactor主要部分啦
接下来看下posixbase.PosixReactorBase这个基类。为什么是PosixReactorBase而不是ReactorBase呢,因为后者是他的父类。。
@implementer(IReactorTCP, IReactorUDP, IReactorMulticast)
class PosixReactorBase(_SignalReactorMixin, _DisconnectSelectableMixin,
ReactorBase):
""" A basis for reactors that use file descriptors. @ivar _childWaker: C{None} or a reference to the L{_SIGCHLDWaker}
which is used to properly notice child process termination.
""" # Callable that creates a waker, overrideable so that subclasses can
# substitute their own implementation:
IReactorTCP, IReactorUDP, IReactorMulticast是定义了PosixReactorBase的套接字方面的一些接口。接口定义的方法不多,源码中实现的还有ListenSSL,listenUNIX,listenUNIXDatagram,甚至adoptStreamPort去兼容IPV6。。he,真不少。 再继续分析PosixReactorBase的混入。
1. _SignalReactorMixin,前面说的单进程只有一个Reactor就是在这里实现的啦。。
而且reactor也不能在stop后再run起来。Reactor在一个进程中只能run一次。。
2、_DisconnectSelectableMixin。这个MixIn只实现了一个方法。来处理haf_close,原理还是在于TCP的4次挥手再见。根据是否完成挥手操作,区分ConnectionLost还是ConnectionDone.
然后终于看这个ReactorBase类了,抽丝剥茧,最后看到的就是就是这个东西。。
@implementer(IReactorCore, IReactorTime, IReactorPluggableResolver)
class ReactorBase(object):
"""
Default base class for Reactors. @type _stopped: C{bool}
@ivar _stopped: A flag which is true between paired calls to C{reactor.run}
and C{reactor.stop}. This should be replaced with an explicit state
machine. @type _justStopped: C{bool}
@ivar _justStopped: A flag which is true between the time C{reactor.stop}
is called and the time the shutdown system event is fired. This is
used to determine whether that event should be fired after each
iteration through the mainloop. This should be replaced with an
explicit state machine. @type _started: C{bool}
@ivar _started: A flag which is true from the time C{reactor.run} is called
until the time C{reactor.run} returns. This is used to prevent calls
to C{reactor.run} on a running reactor. This should be replaced with
an explicit state machine. @ivar running: See L{IReactorCore.running} @ivar _registerAsIOThread: A flag controlling whether the reactor will
register the thread it is running in as the I/O thread when it starts.
If C{True}, registration will be done, otherwise it will not be.
"""
在这里,实现的是IReactorCore,IReactorTime, IReactorPluggableResolver三个接口。。(核心两个字写在脸上了。“打脸”就朝这里)
IReactor实现了什么呢。就是Reacor的主要特点。Event操作。Reactor的开关,和 DNS查询。。。BTW,这点比BaseHTTPServer想的好多了。
后者就直接去查DNS了。而这里放入了事件循环当中,没有去阻塞进程。。
IReactorTime是有关defer对象处理,seconds和callLater什么的。
IReactorPluggableResolver是提供了关于查询DNS的接口,方便自己去实现缓存或者预设DNS,本地DNS 什么的。。
#歇一会儿。。
twisted internet.reactor部分 源码分析的更多相关文章
- twisted 源码分析一:reactor 单例
一个twisted进程只会有一个reactor反应器,下面我们来看看twisted是怎样实现这个单例反应器的, 路径:twisted\internet\reactor.py 主要代码如下: impor ...
- Twisted源码分析系列01-reactor
转载自:http://www.jianshu.com/p/26ae331b09b0 简介 Twisted是用Python实现的事件驱动的网络框架. 如果想看教程的话,我觉得写得最好的就是Twisted ...
- twisted reactor 实现源码解析
twisted reactor 实现源码解析 1. reactor源码解析 1.1. 案例分析代码: from twisted.internet import protocol fro ...
- netty源码分析之揭开reactor线程的面纱(二)
如果你对netty的reactor线程不了解,建议先看下上一篇文章netty源码分析之揭开reactor线程的面纱(一),这里再把reactor中的三个步骤的图贴一下 reactor线程 我们已经了解 ...
- Netty源码分析之Reactor线程模型详解
上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型 在分析源码之前,我们先分析,哪些地方用到了EventLoop? NioServerSocke ...
- Python twisted事件驱动网络框架 源码剖析
一.Twisted简介 Twisted是一个事件驱动的网络框架,其中包含了诸多功能,例如:网络协议.线程.数据库管理.网络操作.电子邮件等. 事件驱动简而言之,事件驱动分为二个部分:第一,注册事件:第 ...
- MyCat源码分析系列之——前后端验证
更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...
- jQuery实现DOM加载方法源码分析
传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... } 但 ...
- Redis学习——ae事件处理源码分析
0. 前言 Redis在封装事件的处理采用了Reactor模式,添加了定时事件的处理.Redis处理事件是单进程单线程的,而经典Reator模式对事件是串行处理的.即如果有一个事件阻塞过久的话会导致整 ...
随机推荐
- Tomcat配置域名访问
在server.xml文件中的<Host>标签里面添加 <Alias>你的域名(比如:www.baidu.com)</Alias> <Context path ...
- mac中vmware tools进行磁盘压缩和vmware-tools-cli的使用方法
前言: 高高兴兴的在vmware9.0中安装了mac10.8系统,然后学习iphone开发,但是发现下载的pdf都是基于xcode3.2.5的,又在10.8上面安装3.2.5,出现“五国”无法解决,最 ...
- Linux 的使用基础---Shell程序设计
Shell是Linux系统中的一个重要的层次,它是用户与系统交互作用的界面.Shell除了作为命令解释程序以外,还是一种高级程序设计语言.利用Shell程序设计语言可以编写出功能很强.但代码简单的程序 ...
- Java多线程中的join()方法
一.join()方法介绍 join() 定义在Thread.java中.join()方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的join( ...
- lex/flex 笔记
Lex的匹配策略: 1. 按最长匹配原则确定被选中的单词 2. 如果一个字符串能被若干正规式匹配,则先匹配排在前面的正规式. lex源程序的写法:Lex源程序必须按照Lex语言的规范来写,其核心是一组 ...
- J2EE项目应用开发过程中的易错点
场景一 实体类型与数据库类型不一致,在进行条件查询过程中不走索引 分析 字段值类型和数据库定义的字段类型不一致时,MySQL就会在内部做数据转化, 它的处理行为就会和我们期望的有些不一样,当我们使用整 ...
- 利用CodeSmith生成抽象工厂步骤
其实CodeSmith挺好的,帮我们主动生成不少代码,并且代码质量不错,下面就来介绍一下利用CodeSmith生成抽象工厂步骤 打开codesmith模板的buildall 注意path的设置,因为后 ...
- 20160506-hibernate入门
HQL和Criteria HQL(Hibernate Query Language) 面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写):HQ ...
- dll不同的调用方式
LoadLibrary 一般是动态加载DLL时(你并不需要对应的头文件,和LIB) #pragma comment 一般是静态加载DLL时(对应的头文件.DLL,和LIB缺一不可,并且生产的EXE没有 ...
- iOS推送通知流程
①注册推送通知使用方法:registerUserNotificationSettings, registerForRemoteNotifications ④APP发送deviceToken到第三方: ...