PythonTip >> 博文 >> Twisted

[SO翻译]Reactor模式和事件驱动模型的区别

zihua 2014-02-24 15:02:34 点击: 1491 | 收藏


[提问 by Howard]

在维基百科(英文) Reactor Pattern 的条目中,有如下描述:

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs.
反应器模式是一种事件处理模式,用于处理从一个或多个来源同时分发到服务处理器的服务请求。

文中举了一些例子,例如 node.jstwistedeventmachine 。但是在我的理解中,上面这些都是流行的“事件驱动框架”——于是它们也就是“反应器模式”的框架?如何区分这两者?或者说,它们是相同的么?

[回答 by Jean-Paul Calderone]

反应器模式 比“事件驱动编程”要更加具体,它是在使用事件驱动方法编程时的一种具体的实现方式。但是在平常的交谈中,这个词的精确意思并不常用。所以,你应该小心使用这个词,确保你的听众能正确理解你的意思;同样,当你遇到他人使用这个词的时候,也要留意你的理解是否与他人的本意有所偏差。

看待反应器模式的一种方式是将其与“非阻塞操作”密切联系起来。当某个操作可以不被阻塞地完成时,反应器就会发出通知。例如, select(2) 可以实现反应器模式,以便使用标准的BSD Socket API( recv(2)send(2) 等等)来读写socket。例如,当你可以从一个socket读取的时候——因为这个socket在系统内核中的接收缓存中有字节可读—— select 就会立刻告诉你。

在考虑这些概念的时候,另一个你可能会感兴趣的模式就是 前摄器模式(Proactor Pattern) 。与反应器模式正好相反,前摄器模式不考虑操作是否能够立刻完成,而是直接开始操作,使其异步执行,并等它完成之后再安排分发事件通知。

Windows I/O Completion Ports(IOCP) 就是前摄器模式的一个例子。当使用IOCP在一个socket上进行发送操作的时候,该操作会立刻开始,无论这个socket的内核发送缓存是否有空间来容纳数据;当 WSASend 调用完成的时候,发送操作才会继续(在另一个线程里,可能是在一个系统线程里)。当发送操作 真的 完成了(即要发送的所有字节全都已经被复制到发送缓存之后),提供给 WSASend 调用的 回调函数 就会被执行(在应用程序的新线程里)。

这种发起操作并在完成时得到通知的做法,正是异步操作思想的核心。而非阻塞操作,则是只有当操作可以立刻完成的时候才发起操作,否则将一直等待。

这两种方式都可以用来进行事件驱动的开发。使用反应器模式的时候,程序将等待例如“某个socket可读了”的事件,当事件发生时,就去读取;而使用前摄器模式的时候,程序则直接发起读取的操作,并等待读取结束事件的发生(然后对结果进行处理)。

严格地说, Twisted 误用了 Reactor 这个词。 The Twisted reactor 基于 select(2) 并以非阻塞IO的方式实现,这几乎就是一个反应器;但是,它提供给使用者的接口是 异步 的,这一部分更像是前摄器。 Twisted 还有一个基于IOCP的反应器,这个反应器为应用程序提供的也是异步的API,并且使用了前摄器式的IOCP API。它是一个混血,而且在不同平台上有着不同的实现细节,因此,用 ReactorProactor 来描述都不准确。不过,由于 twisted.internet.reactor 里提供的API基本全都是异步API,而非“非阻塞”API,用 Procator 来称呼 Twisted 应该会更加合适。

[回答者追加评论摘要]

select(2) 是非常底层的,而且很难使用。当有很多个事件源的时候,它还不够高效。现代的系统提供了功能相同但更加高效的API,如/dev/poll,epoll等。Twisted及类似的库的好处在于,它们提供了对各种不同实现方式的抽象,使得应用程序可以使用一套统一的API,同时仍然能享受到底层系统提供的高效API的支持。

select(2)和epoll(4)的比较,可以参考这篇Q&A: Caveats of select/poll vs. epoll reactors in Twisted

原文链接:http://www.tuicool.com/articles/aqEfiq

作者:zihua | 分类: Twisted | 标签: twisted | 阅读: 1491 | 发布于: 2014-02-24 15时 |