twisted internet.reactor部分 源码分析

时间:2022-06-23 06:29:34

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. C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

    在上篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及对应的对象模型,本篇继续微信小店的主题,介绍其中API接口的封装和测试使用.微信小店的相 ...

  2. 动作手游实时PVP帧同步方案(客户端)

    1.概述 1.1.基于UDP的帧同步方案 在技术选型方面,之所以选择帧同步方案,在Kevin的一篇介绍PVP帧同步后台实现的文章中已经做了详细叙述,这里简单摘要如下: 高一致性.如果每一帧的输入都同步 ...

  3. mysql时间格式化&comma;按时间段查询MYSQL语句

    描述:有一个会员表,有个birthday字段,值为'YYYY-MM-DD'格式,现在要查询一个时间段内过生日的会员,比如'06-03'到'07-08'这个时间段内所有过生日的会员. SQL语句: Se ...

  4. AJAX-----16HTML5实现大文件切割上传

    2点多接了个电话导致失眠,没办法,跑起来接着板砖了...... 废话不多说,直接走码... <!DOCTYPE html> <html lang="en"> ...

  5. HW5&period;8

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\t%s\ ...

  6. &commat;ManyToMany中间表附加字段设计

    在使用@ManyToMany时,若中间表只有相应的外键字段可以直接建立两个对应的Entity 设置ManyToMany @ManyToMany 两个表多对多关联 但若是中间表有自己的附加字段,这需要为 ...

  7. Swift - 26 - 函数的基础写法

    //: Playground - noun: a place where people can play import UIKit // 无参无返回 // -> Void可以省略不写, 或者写成 ...

  8. wpf之ListBox中ListBoxItem横向排列

    ListBox中ListBoxItem默认是纵向排列,可以通过自定义样式,让其横向排列, 如下Demo: XAML: <Window x:Class="ListBoxItemStyle ...

  9. laravel belongsTo使用

    前提:订单表(order)和用户表(user) 表结构: order CREATE TABLE `order` ( `id` char(16) COLLATE utf8mb4_unicode_ci N ...

  10. sql语句优化总结

    sql语句优化总结 数据库优化的几个原则: 1.尽量避免在列上做运算,这样会导致索引失败: 2.使用join是应该用小结果集驱动大结果集,同时把复杂的join查询拆分成多个query.不然join的越 ...