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部分 源码分析的更多相关文章

  1. twisted 源码分析一:reactor 单例

    一个twisted进程只会有一个reactor反应器,下面我们来看看twisted是怎样实现这个单例反应器的, 路径:twisted\internet\reactor.py 主要代码如下: impor ...

  2. Twisted源码分析系列01-reactor

    转载自:http://www.jianshu.com/p/26ae331b09b0 简介 Twisted是用Python实现的事件驱动的网络框架. 如果想看教程的话,我觉得写得最好的就是Twisted ...

  3. twisted reactor 实现源码解析

    twisted reactor 实现源码解析 1.      reactor源码解析 1.1.    案例分析代码: from twisted.internet import protocol fro ...

  4. netty源码分析之揭开reactor线程的面纱(二)

    如果你对netty的reactor线程不了解,建议先看下上一篇文章netty源码分析之揭开reactor线程的面纱(一),这里再把reactor中的三个步骤的图贴一下 reactor线程 我们已经了解 ...

  5. Netty源码分析之Reactor线程模型详解

    上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型 在分析源码之前,我们先分析,哪些地方用到了EventLoop? NioServerSocke ...

  6. Python twisted事件驱动网络框架 源码剖析

    一.Twisted简介 Twisted是一个事件驱动的网络框架,其中包含了诸多功能,例如:网络协议.线程.数据库管理.网络操作.电子邮件等. 事件驱动简而言之,事件驱动分为二个部分:第一,注册事件:第 ...

  7. MyCat源码分析系列之——前后端验证

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...

  8. jQuery实现DOM加载方法源码分析

    传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但 ...

  9. Redis学习——ae事件处理源码分析

    0. 前言 Redis在封装事件的处理采用了Reactor模式,添加了定时事件的处理.Redis处理事件是单进程单线程的,而经典Reator模式对事件是串行处理的.即如果有一个事件阻塞过久的话会导致整 ...

随机推荐

  1. WSGI、flup、fastcgi、web.py的关系

    Apache/lighttpd: 相当于一个request proxy,根据配置,把不同的请求转发给不同的server处理,例如静态的文件请求自己处理,这个时候它就像一个web server,对于fa ...

  2. PHP为fopen,file_get_contents等函数请求web地址时增加Http头的方法

    我们在使用fsockopen时可以方便的自定义自己请求的http头内容来访问某些对客户端请求头有特殊限制的网站,但是使用fopen,file_get_contents等函数请求web地址时怎么来灵活定 ...

  3. Using zend-navigation in your Album Module

    Using zend-navigation in your Album Module In this tutorial we will use the zend-navigation componen ...

  4. sql基本语法:

    1.create database db_name; --创建数据库 2.drop database db_name;  --删除数据库 3.show create database db_name\ ...

  5. 关于SWT的容器类之----面板Composite类和Group类

    1.Comosite类谱系图. Composite的用法: 格式:Composite(Composite parent,int style) 用法:Composite composite = new ...

  6. Floyd判圈算法(判断是否有环)

    介意转吗博主~~http://blog.csdn.net/thestoryofsnow/article/details/6822576,我知道不介意啦~ 问题:如何检测一个链表是否有环,如果有,那么如 ...

  7. mongodb用mongoose取到的对象不能增加属性

    先定义了一个article的schema var mongoose = require('mongoose'); var Schema = mongoose.Schema; exports.schem ...

  8. hihocoder 1163 博弈游戏·Nim游戏

    1163 : 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob. Alice与Bob总是在进行各种各样的 ...

  9. hackerrank Day 10: Binary Numbers

    Task Given a base-10 integer, n, convert it to binary (base-2). Then find and print the base-10 inte ...

  10. 阿里云 mysql 无缘无故挂掉

    近期在登录自己博客时,老是报数据库连接失败,然后重启服务器就好了.但是,重启服务器很耗时间,不方便,不能每次都重启吧于是远程连接服务器看了一下原来是数据库服务挂掉了启动时还报错于是查看了下错误日志 2 ...