Python 的 Twisted Reactor 是如何工作的? [英] How does Python's Twisted Reactor work?

查看:44
本文介绍了Python 的 Twisted Reactor 是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我一直在研究 Twisted 文档.从我收集到的信息来看,Twisted 功能的基础是其称为反应器"的事件循环的结果.反应器侦听某些事件并将它们分派到已注册的回调函数,这些回调函数旨在处理这些事件.在书中,有一些伪代码描述了 Reactor 的作用,但我无法理解它,这对我来说没有任何意义.

Recently, I've been diving into the Twisted docs. From what I gathered, the basis of Twisted's functionality is the result of it's event loop called the "Reactor". The reactor listens for certain events and dispatches them to registered callback functions that have been designed to handle these events. In the book, there is some pseudo code describing what the Reactor does but I'm having trouble understanding it, it just doesn't make any sense to me.

 while True:
     timeout = time_until_next_timed_event()
     events = wait_for_events(timeout)
     events += timed_events_until(now())
     for event in events:
         event.process()

这是什么意思?

推荐答案

如果不明显,它被称为反应器,因为它反应东西.循环是如何反应.

In case it's not obvious, It's called the reactor because it reacts to things. The loop is how it reacts.

一次一行:

while True:

这不是实际上 while True;它更像是 while not loop.stopped.您可以调用 reactor.stop() 来停止循环,并且(在执行一些关闭逻辑之后)循环实际上将退出.但它在示例中被描述为 while True 因为当你编写一个长期存在的程序时(就像你经常使用 Twisted 一样),最好假设你的程序要么崩溃,要么永远运行,而彻底退出"并不是一个真正的选择.

It's not actually while True; it's more like while not loop.stopped. You can call reactor.stop() to stop the loop, and (after performing some shut-down logic) the loop will in fact exit. But it is portrayed in the example as while True because when you're writing a long-lived program (as you often are with Twisted) it's best to assume that your program will either crash or run forever, and that "cleanly exiting" is not really an option.

     timeout = time_until_next_timed_event()

如果我们稍微扩展一下这个计算,可能会更有意义:

If we were to expand this calculation a bit, it might make more sense:

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 在特定时间运行的功能.

timed_events is the list of events scheduled with reactor.callLater; i.e. the functions that the application has asked for Twisted to run at a particular time.

     events = wait_for_events(timeout)

这里的这一行是 Twisted 的神奇"部分.我不能以一般方式扩展 wait_for_events,因为它的实现完全取决于操作系统如何使所需的事件可用.而且,鉴于操作系统是复杂而棘手的野兽,我无法以特定方式对其进行扩展,同时保持足够简单以回答您的问题.

This line here is the "magic" part of Twisted. I can't expand wait_for_events in a general way, because its implementation depends on exactly how the operating system makes the desired events available. And, given that operating systems are complex and tricky beasts, I can't expand on it in a specific way while keeping it simple enough for an answer to your question.

这个函数的意思是,要求操作系统或它周围的 Python 包装器阻塞,直到一个或多个先前向它注册的对象 - 至少,诸如侦听端口和已建立的连接之类的东西,但也可能像按钮之类的东西可能会被点击 - 是准备工作".当它们从网络到达时,工作可能会从套接字中读取一些字节.当缓冲区足够清空以执行此操作时,工作可能会向网络写入字节.它可能正在接受新连接或处理关闭的连接.这些可能的事件中的每一个都是反应器可能对您的对象调用的函数:dataReceivedbuildProtocolresumeProducing 等,您将了解这些如果你阅读了完整的 Twisted 教程.

What this function is intended to mean is, ask the operating system, or a Python wrapper around it, to block, until one or more of the objects previously registered with it - at a minimum, stuff like listening ports and established connections, but also possibly things like buttons that might get clicked on - is "ready for work". The work might be reading some bytes out of a socket when they arrive from the network. The work might be writing bytes to the network when a buffer empties out sufficiently to do so. It might be accepting a new connection or disposing of a closed one. Each of these possible events are functions that the reactor might call on your objects: dataReceived, buildProtocol, resumeProducing, etc, that you will learn about if you go through the full Twisted tutorial.

一旦我们获得了假设的事件"对象列表,每个对象都有一个虚构的process"方法(反应堆中方法的确切名称因事故而不同历史),然后我们回到处理时间:

Once we've got our list of hypothetical "event" objects, each of which has an imaginary "process" method (the exact names of the methods are different in the reactor just due to accidents of history), we then go back to dealing with time:

     events += timed_events_until(now())

首先,这是假设 events 只是一个抽象 Event 类的 list,它有一个 process> 每种特定类型的事件需要填写的方法.

First, this is assuming events is simply a list of an abstract Event class, which has a process method that each specific type of event needs to fill out.

此时,循环已经唤醒",因为wait_for_events,停止阻塞.但是,我们不知道根据休眠"了多长时间,我们可能需要执行多少个定时事件.如果没有发生任何事情,我们可能已经睡了完全超时,但如果有很多连接处于活动状态,我们可能根本没有睡.因此,我们检查当前时间(now()"),然后将每个定时事件添加到我们需要处理的事件列表中,其中 desired_time 位于,或之前,当前时间.

At this point, the loop has "woken up", because wait_for_events, stopped blocking. However, we don't know how many timed events we might need to execute based on how long it was "asleep" for. We might have slept for the full timeout if nothign was going on, but if lots of connections were active we might have slept for effectively no time at all. So we check the current time ("now()"), and we add to the list of events we need to process, every timed event with a desired_time that is at, or before, the present time.

最后,

     for event in events:
         event.process()

这只是意味着 Twisted 会检查它必须做的事情的列表并执行它们.在现实中当然它会处理每个事件周围的异常,并且反应器的具体实现通常只是直接调用事件处理程序,而不是创建一个类似 Event 的对象来记录需要完成的工作首先,但从概念上讲,这正是发生的事情.event.process 在这里可能意味着调用 socket.recv() 然后 yourProtocol.dataReceived 和结果,例如.

This just means that Twisted goes through the list of things that it has to do and does them. In reality of course it handles exceptions around each event, and the concrete implementation of the reactor often just calls straight into an event handler rather than creating an Event-like object to record the work that needs to be done first, but conceptually this is just what happens. event.process here might mean calling socket.recv() and then yourProtocol.dataReceived with the result, for example.

我希望这个扩展的解释能帮助你理解它.如果你想通过研究了解更多关于 Twisted,我鼓励你 加入邮件列表,跳到 IRC 频道,#twisted 谈论应用程序或 #twisted-dev 在 Twisted 本身上工作,两者都是在 Freenode 上.

I hope this expanded explanation helps you get your head around it. If you'd like to learn more about Twisted by working on it, I'd encourage you to join the mailing list, hop on to the IRC channel, #twisted to talk about applications or #twisted-dev to work on Twisted itself, both on Freenode.

这篇关于Python 的 Twisted Reactor 是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆