2008-09-17 72 views
29

我在Twisted中开发反向代理时遇到问题。它有效,但它似乎过于复杂和复杂。如此多的感觉就像伏都教。Python中的异步编程扭曲

是否有任何简单,坚实在网络或书籍上的异步程序结构的例子?一种最佳实践指南?当我完成我的计划时,我希望能够以某种方式看到结构,而不是看一碗意大利面条。

+5

我希望你有更好的运气,它是目前我最喜欢的框架之一。 – Dustin 2008-11-30 06:02:11

回答

0

如果你不想使用扭曲有一个很好的指导,我用了一阵子回来。这里是link to it

64

Twisted包含一个large number of examples。其中之一"evolution of Finger" tutorial详细解释了异步程序如何从一个非常小的内核发展到一个拥有大量运动部件的复杂系统。另一个你可能感兴趣的是简单的教程writing servers

牢记约扭曲,甚至是其他异步网络库(如asyncoreMINA,或ACE)关键的一点是,有事时你的代码只被调用。我最常听到的部分听起来像“伏都教”,是回调的管理:例如,Deferred。如果您习惯于编写直线运行的代码,并且只调用立即返回结果的函数,那么等待某些回调函数的想法可能会让您感到困惑。但没有什么不可思议的,没有关于回调的“巫术”。在最低水平,反应堆只是坐在四周,等待为数不多的事情之一发生:

  1. 数据到达一个连接上(它会调用dataReceived一个协议上)
  2. 时间已经过去了(它将调用使用callLater注册的功能)。
  3. 连接已被接受(它将在注册了listenXXXconnectXXX函数的工厂上调用buildProtocol)。
  4. 的连接已被删除(它会调用connectionLost相应的协议上)

每个异步程序启动钩住了一些这些事件,然后拉开反应器等待他们的出现。当然,发生的事件会导致更多事件挂钩或断开连接,因此您的程序将以愉快的方式继续进行。除此之外,异步程序结构没有什么特别的,它们是有趣或特殊的;事件处理程序和回调只是对象,并且您的代码以通常的方式运行。

下面是一个简单的“事件驱动引擎”,它向你展示了这个过程是多么简单。

# Engine 
import time 
class SimplestReactor(object): 
    def __init__(self): 
     self.events = [] 
     self.stopped = False 

    def do(self, something): 
     self.events.append(something) 

    def run(self): 
     while not self.stopped: 
      time.sleep(0.1) 
      if self.events: 
       thisTurn = self.events.pop(0) 
       thisTurn() 

    def stop(self): 
     self.stopped = True 

reactor = SimplestReactor() 

# Application  
def thing1(): 
    print 'Doing thing 1' 
    reactor.do(thing2) 
    reactor.do(thing3) 

def thing2(): 
    print 'Doing thing 2' 

def thing3(): 
    print 'Doing thing 3: and stopping' 
    reactor.stop() 

reactor.do(thing1) 
print 'Running' 
reactor.run() 
print 'Done!' 

在像扭曲库的核心,在主回路的功能是不sleep,但操作系统调用等select()poll(),如暴露由模块等the Python select module。我说“像”select,因为这是一个平台之间差异很大的API,几乎每个GUI工具包都有自己的版本。 Twisted目前为这个主题提供了14种不同变体的抽象界面。这种API提供的共同点是提供一种方式来说:“这是我正在等待的事件列表。去睡觉,直到其中一个发生,然后醒来,告诉我它是哪一个。“