文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>学习 Twisted 的 reactor (1)

学习 Twisted 的 reactor (1)

时间:2007-05-18  来源:ahhy


    Twisted Matrix 是一种用来进行网络服务和应用程序的编程纯 Python 框架。并且该框架的中心概念还是非阻塞异步服务器。
      下面开始学习 twisted 中的 reactor 机制(反应器)。以下是一个非常常见的 Twisted 启动 reactor 的代码:  

from twisted.internet import reactor
        from twisted.internet.protocol import Protocol
        from twisted.internet.protocol import Factory
        
        factory = Factory()
        factory.protocol = YourHandler
        
        if __name__=='__main__':
            reactor.listenTCP(8888, factory)
            reactor.run()

      从这段代码的 “标识” 含义也能猜出作用:首先可以作为一个服务器端,启动一个在 8888 端口上的基于 TCP 的监听器,并且该监听器对于每一个客户端的请求会使用由 factory 指定的处理器(YourHandler),由该处理器来与客户端进行下面的交互。       或许看一下 reactor 的相关源代码会让我们更清楚这家伙在后面做了些什么(毕竟 “源码之前,了无秘密” )


    -- /twisted/internet/reactor.py
    """
    See twisted.internet.interfaces.IReactor*.
    """
    import sys
    del sys.modules['twisted.internet.reactor']
    #from twisted.python import log
    #log.msg("Installing SelectReactor, since unspecified.")
    from twisted.internet import selectreactor
    selectreactor.install()

    晕了,这段代码一上来就把 twisted.internet.reactor 模块给 del 了,但是下面又倒入了 selectreactor 模块了,继续跟进,找到 selectreactor.install():  

-- /twisted/internet/selectreactor.py

    def install():
        """Configure the twisted mainloop to be run using the select() reactor.
        """
        reactor = SelectReactor()
        from twisted.internet.main import installReactor
        installReactor(reactor)

    
    在一开始,创建了 SelectReactor(根据名字也可以知道该 reactor 是基于 select() 的) 的一个实例,而 SelectReactor 又是派生自 posixbase.PosixReactorBase 的 -- 一个基于文件描述符的 reactor,又跟进一下 posixbase.PosixReactorBase,可知又派生自 ReactorBase 类,并且在创建实例的时候在 ReactorBase 里做了一些和系统相关的初始化工作,如下代码:
 

-- /twisted/internet/base.py

    class ReactorBase(object):
        """Default base class for Reactors.
        """
    
        implements(IReactorCore, IReactorTime, IReactorPluggableResolver)
        ...
        __name__ = "twisted.internet.reactor"
    
        def __init__(self):
            self.threadCallQueue = [] // 1
            self._eventTriggers = {} // 2
            self._pendingTimedCalls = []
            self._newTimedCalls = []
            self._cancellations = 0
            self.running = 0
            self.waker = None
    
            // 3
            self.addSystemEventTrigger('during', 'shutdown', self.crash)
            self.addSystemEventTrigger('during', 'shutdown', self.disconnectAll)
    
            if platform.supportsThreads():
                self._initThreads()
        ...

    呵呵,到这里还真的做了一些事情了:

        * 1,初始化线程调用队列
        * 2,初始化事件触发器s  (reactor 为事件触发机制)
        * 3,addSystemEventTrigger(添加 system 事件触发器),可能是我们非常需要知道的了:)
   
    下面再看看这个方法做哪些细节的事情:
 

-- /twisted/internet/base.py
 
    class ReactorBase(object):
        ... ...
        def addSystemEventTrigger(self, _phase, _eventType, _f, *args, **kw):
            """See twisted.internet.interfaces.IReactorCore.addSystemEventTrigger.
            """
            assert callable(_f), "%s is not callable" % _f
            if self._eventTriggers.has_key(_eventType):
                triglist = self._eventTriggers[_eventType]
            else:
                triglist = [[], [], []]
                self._eventTriggers[_eventType] = triglist
            evtList = triglist[{"before": 0, "during": 1, "after": 2}[_phase]]
            evtList.append((_f, args, kw))
            return (_phase, _eventType, (_f, args, kw))

    可见,在该方法主要用于添加我们需要注册(关注)的事件,以及对应的处理方法的,并且对于每一个系统事件(system event),如 startup(启动), shutdown(关闭), persist(持续),都有三种状态:'before', 'during', 'after'。

    并且这些都由 Reactor 进行触发,并对相应的事件及状态调用指定的(注册的)方法 -- 即这里的参数 _f 指定的 callable 对象。           * self._eventTriggers   为一个字典(由上的源代码可知),保存了事件类型(_eventType) 与具体的触发器(列表) -- triglist 之间的对应关系           * triglist [[],[],[]]   该触发器列表只有三个元素(即对应于三种不同的状态,before, during, after)           * (_phase, _eventType, (_f, args, kw))  分别对应 “事件状态”,“事件类型”,“方法,及其对应的参数列表”       说白了,就是这么个情况:每个事件类型有三种状态,而每种状态可能对应不同的方法。(可能有点像说气话了)       让我们再回到 selectreactor.py 中的 install() 方法(是该透透气了:)),还没完,里面又调用了 installReactor(reactor) 了,  

-- /twisted/internet/main.py

    CONNECTION_DONE = error.ConnectionDone('Connection done')
    CONNECTION_LOST = error.ConnectionLost('Connection lost')
    
    def installReactor(reactor):
        # this stuff should be common to all reactors.
        import twisted.internet
        import sys
        assert not sys.modules.has_key('twisted.internet.reactor'), \
               "reactor already installed"
        twisted.internet.reactor = reactor
        sys.modules['twisted.internet.reactor'] = reactor

      还记得 /twisted/internet/reactor.py 中一开始就将 twisted.internet.reactor 给 del 掉了的吧,这里又换种途径 “弥补” 了回来了(恩,出来混的,迟早是要还的:)),并且是一个已经初始化了的有效的 reactor 实例了。    
    头上有点冒汗了,才刚初始化 initialize 就冒汗了,希望是兴奋的汗水,不过应该是夏天了,是有点热了,吃根冰棍后继续 ... ...
   

 

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载