Скрученный содержит large number of examples. Один из них, в частности, "evolution of Finger" tutorial, содержит подробное объяснение того, как асинхронная программа растет с очень маленького ядра до сложной системы с большим количеством движущихся частей. Еще один интерес, который может вас заинтересовать, - это учебник о writing servers.
Главное, чтобы иметь в виду о Twisted, или даже других библиотек асинхронной сети (такие как asyncore, MINA или ACE), является то, что ваш код только получает вызывается, когда что-то происходит. Часть, которую я слышал чаще всего, звучит как «voodoo» - это управление обратными вызовами: например, Deferred
. Если вы привыкли писать код, который работает по прямой, и только вызывает функции, которые немедленно возвращаются с результатами, идея ждать чего-то, чтобы перезвонить вам может быть запутанной. Но нет ничего волшебного, никакого «вуду» о обратных вызовах. На самом низком уровне, реактор просто сидит и ждет один из небольшого количества вещей, чтобы случиться:
- Данные поступают на подключении (он будет вызывать
dataReceived
по протоколу)
- Времени прошло (он будет вызывать функцию, зарегистрированную в
callLater
).
- Соединение было принято (он назовет
buildProtocol
на заводе, зарегистрированном с функцией listenXXX
или connectXXX
).
- соединение уронили (он будет вызывать
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, - это способ сказать: «Вот список событий, которые я жду. Идите спать, пока не произойдет одно из них, затем проснитесь и скажите мне, какой из них он был.«
Надеюсь, вам повезло с искривленным. В настоящее время это одна из моих любимых фреймворков. – Dustin 2008-11-30 06:02:11