万一它不明显,之所以称为 反应堆, 是因为它对 事物 有 反应 。循环是 如何 它反应。
一次一行:
while True:
实际上 不是while True
;更像是while not loop.stopped
。您可以调用reactor.stop()
停止循环,并且(在执行一些关闭逻辑之后)循环实际上将退出。但这是在示例中描述的,while True
因为当您编写一个寿命很长的程序时(就像您经常使用Twisted一样),最好假设您的程序将崩溃或永远运行,并且“干净退出”并不是真的一个选项。
timeout = time_until_next_timed_event()
如果我们稍微扩展一下此计算,则可能更有意义:
def time_until_next_timed_event():
Now = time.time()
timed_events.sort(key=lambda event: event.desired_time)
soonest_event = timed_events[0]
return soonest_event.desired_time - Now
timed_events
是预定的活动清单reactor.callLater
; 即应用程序要求Twisted在特定时间运行的功能。
events = wait_for_events(timeout)
这条线是Twisted的“魔术”部分。我无法wait_for_events
以一般方式进行扩展,因为其实现方式完全取决于操作系统如何使所需的事件可用。而且,由于操作系统是复杂而棘手的野兽,因此我无法以特定的方式对其进行扩展,同时又要使其足够简单以回答您的问题。
此功能的意思是,要求操作系统或其周围的Python包装器阻塞,直到一个或多个先前向其注册的对象为止- 至少包括诸如侦听端口和已建立的连接之类的内容,而且诸如可能会被点击的按钮之类的东西可能已经“准备工作”。当它们从网络到达时,工作可能正在从套接字读取一些字节。当缓冲区清空时,可能会将字节写入网络。它可能正在接受新的连接,也可能正在处理关闭的连接。每个可能的事件是功能的反应堆可能会在你的对象调用:dataReceived
,buildProtocol
,resumeProducing
,等等,你会了解,如果你去通过充分扭曲的教程。
一旦获得了假设的“事件”对象的列表,每个对象都有一个假想的“process
”方法(由于历史的偶然性,反应堆中方法的确切名称有所不同),然后我们将继续处理时间:
events += timed_events_until(Now())
首先,假设events
这只是一个list
抽象Event
类的,它具有一种process
方法,每种特定类型的事件都需要填写。
此时,循环已“唤醒”,因为已wait_for_events
停止阻塞。但是,我们不知道根据 “睡眠”了多长时间, 我们可能需要执行多少个定时事件。如果没有发生冲突,我们可能已经睡了整个超时时间,但是如果有很多连接处于活动状态,那么我们可能根本没有时间睡。因此,我们检查当前时间(“Now()
”),然后将需要处理的事件列表添加到desired_time
当前时间或当前时间之前的每个定时事件。
最后,
for event in events:
event.process()
这仅意味着Twisted遍历了必须要做的事情并完成了这些事情。实际上,实际上它会处理每个事件的异常,而反应堆的具体实现通常只是直接调用事件处理程序,而不是创建Event
类似对象的对象来记录需要首先完成的工作,但是从概念上讲,这就是事实发生。event.process
例如,此处可能意味着先调用socket.recv()
然后再返回yourProtocol.dataReceived
结果。
我希望这个扩展的解释可以帮助您有所了解。如果您想通过使用它来了解更多有关Twisted的信息,我鼓励您加入邮件列表,跳至IRC频道,#twisted
讨论应用程序或#twisted- dev
在Twisted上进行开发,两者都在Freenode上进行。