事件驱动模型和反应器模式有什么区别?

发布于 2025-01-03 03:33:04 字数 337 浏览 3 评论 0原文

来自维基百科反应器模式文章:

反应器设计模式是一种事件处理模式,用于处理通过一个或多个输入并发传递到服务处理程序的服务请求。

它举了几个例子,例如 nodejstwistedeventmachine

但我理解上面的是流行的事件驱动框架,所以让它们也成为反应堆模式框架?

如何区分这两者?或者它们是相同的?

From the wikipedia Reactor Pattern article:

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs.

It named a few examples, e.g. nodejs, twisted, eventmachine

But what I understand that above is popular event driven framework, so make them also a reactor pattern framework?

How to differentiate between these two? Or they are the same?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逆光下的微笑 2025-01-10 03:33:04

反应器模式比“事件驱动编程”更具体。它是进行事件驱动编程时使用的一种特定实现技术。然而,该术语在典型对话中的使用不太准确,因此您应该谨慎使用它并期望您的听众能够理解您的意思,并且当您遇到该术语的使用时,您应该小心如何解释该术语。

查看反应器模式的一种方法是考虑它与“非阻塞”操作的思想密切相关。当某些操作可以在不阻塞的情况下完成时,反应器会发出通知。例如,select(2) 可用于实现反应器模式,以便使用标准 BSD 套接字 API (recv(2)>发送(2)等)。 select 会告诉您何时可以立即从套接字接收字节 - 例如,因为这些字节存在于该套接字的内核接收缓冲区中。

在思考这些想法时您可能需要考虑的另一种模式是proactor模式。与反应器模式相反,前摄器模式让操作开始,无论它们是否可以立即完成,让它们异步执行,然后安排传递有关其完成的通知。

Windows I/O 完成端口 (IOCP) API 是可以看到前摄器模式的一个示例。当使用 IOCP 在套接字上执行发送时,无论内核发送缓冲区中是否有该套接字的空间,都会启动发送操作。发送操作继续(在另一个线程中,可能是内核中的线程),而 WSASend 调用立即完成。当发送实际完成时(仅意味着正在发送的字节已被复制到该套接字的内核发送缓冲区中),将调用提供给 WSASend 调用的回调函数(在应用程序的新线程中)。

这种启动操作并在操作完成时收到通知的方法是异步操作思想的核心。将其与非阻塞操作进行比较,在非阻塞操作中,您会等到操作立即完成后再尝试执行它。

任一方法都可用于事件驱动编程。使用反应器模式,程序等待(例如)套接字可读的事件,然后从中读取。使用前摄器模式,程序会等待套接字读取完成的事件

严格来说,Twisted 误用了术语“反应器”。 Twistedreactor基于select(2) (twisted.internet.selectreactor),使用非阻塞I/O实现,非常类似于reactor。然而,它向应用程序代码公开的接口是异步的,这使得它更像前摄器。 Twisted还有一个基于IOCP的反应器。该反应器公开相同的面向异步应用程序的 API使用类似前摄器的 IOCP API。这种混合方法的细节因平台而异,因此术语“reactor”和“proactor”都不是特别准确,但由于 twisted.internet.reactor 公开的 API 基本上是完全异步的对于非阻塞,proactor 可能是更好的名称选择。

The reactor pattern is more specific than "event driven programming". It is a specific implementation technique used when doing event driven programming. However, the term is not used with much accuracy in typical conversation, so you should be careful about using it and expecting your audience to understand you, and you should be careful in how you interpret the term when you encounter its use.

One way to look at the reactor pattern is to consider it closely related to the idea of "non-blocking" operations. The reactor sends out notifications when certain operations can be completed without blocking. For example, select(2) can be used to implement the reactor pattern for reading from and writing to sockets using the standard BSD socket APIs (recv(2), send(2), etc). select will tell you when you can receive bytes from a socket instantly - because the bytes are present in the kernel receiver buffer for that socket, for example.

Another pattern you might want to consider while thinking about these ideas is the proactor pattern. In contrast to the reactor pattern, the proactor pattern has operations start regardless of whether they can finish immediately or not, has them performed asynchronously, and then arranges to deliver notification about their completion.

The Windows I/O Completion Ports (IOCP) API is one example where the proactor pattern can be seen. When performing a send on a socket with IOCP, the send operation is started regardless of whether there is any room in the kernel send buffer for that socket. The send operation continues (in another thread, perhaps a thread in the kernel) while the WSASend call completes immediately. When the send actually completes (meaning only that the bytes being sent have been copied into the kernel send buffer for that socket), a callback function supplied to the WSASend call is invoked (in a new thread in the application).

This approach of starting operations and then being notified when they are complete is central to the idea of asynchronous operations. Compare it to non-blocking operations where you wait until an operation can complete immediately before attempting to perform it.

Either approach can be used for event driven programming. Using the reactor pattern, a program waits for the event of (for example) a socket being readable and then reads from it. Using the proactor pattern, the program instead waits for the event of a socket read completing.

Strictly speaking, Twisted misuses the term reactor. The Twisted reactor which is based on select(2) (twisted.internet.selectreactor) is implemented using non-blocking I/O, which is very reactor-like. However, the interface it exposes to application code is asynchronous, making it more proactor-like. Twisted also has a reactor based on IOCP. This reactor exposes the same asynchronous application-facing API and uses the proactor-like IOCP APIs. This hybrid approach, varying from platform to platform in its details, makes neither the term "reactor" nor "proactor" particularly accurate, but since the API exposed by twisted.internet.reactor is basically entirely asynchronous instead of non-blocking, proactor would probably have been a better choice of name.

人心善变 2025-01-10 03:33:04

我认为这种“非阻塞”和“异步”的分离是错误的,因为“异步”的主要含义是“非阻塞”。反应堆模式是关于异步(非阻塞)调用,但这些调用的同步(阻塞)处理。 Proactor 涉及异步(非阻塞)调用以及这些调用的异步(非阻塞)处理。

I think that this separation "non-blocking" and "asynchronous" is wrong, as the main implication of "asynchronous" is "non-blocking". Reactor pattern is about asynchronous (so non-blocking) calls, but synchronous (blocking) processing of those calls. Proactor is about asynchronous (non-blocking) calls and asynchronous (non-blocking) processing of those calls.

爱已欠费 2025-01-10 03:33:04

为了处理 TCP 连接,有两种相互竞争的 Web 架构,即基于线程的架构和事件驱动的架构。

基于线程的体系结构

实现多线程服务器的最古老的方法是遵循“每个连接线程”方法。为了控制和限制正在运行的线程的数量,可以将单个调度程序线程与有界阻塞队列和线程池一起使用。

调度程序在 TCP 套接字上阻塞新连接,并将它们提供给有界阻塞队列。超过队列界限的 TCP 连接将被丢弃,从而允许已接受的连接以理想且可预测的延迟运行。

事件驱动架构

将线程与连接分离,事件驱动架构只允许线程用于特定处理程序上的事件。

这个创意概念让反应堆模式走出架子并炫耀。基于此架构构建的系统由事件创建者和事件消费者组成。

反应堆模式

反应堆模式是用于 TCP 连接处理的事件驱动架构中最流行的实现技术。简单来说,它使用单线程事件循环,阻塞事件并将这些事件分派给相应的处理程序。

只要注册事件处理程序来处理它们,其他线程就不需要阻塞 I/O。考虑到 TCP 连接,我们可以轻松地将事件引用到这些实例:已连接、输入就绪、输出就绪、超时和断开连接。

反应堆模式将模块化应用程序级代码与可重用反应堆实现解耦。为了实现这一点,反应器模式的架构由两个重要的参与者组成——反应器和处理程序。

反应器

反应器在单独的线程中运行,它通过将工作分派到适当的注册处理程序来对 I/O 事件做出反应,例如连接、输入就绪、输出就绪、超时和断开连接。

处理程序

处理程序执行实际工作或需要通过 I/O 事件完成的响应。 Reactor 通过调度适当的处理程序来响应 I/O 事件。

Jim Coplien 和 Douglas C. Schmidt 于 1995 年出版的《程序设计的模式语言》是详细解释 Reactor 模式的书籍之一。

To handle TCP connections, there are two competing web architectures, namely thread-based architecture and event-driven architecture.

Thread-Based Architecture

The oldest way of implementing a multi-threaded server is following the “thread per connection” approach. In order to control and limit the number of running threads, a single dispatcher thread can be used along with a bounded blocking queue and a thread pool.

The dispatcher blocks on a TCP socket for new connections and offers them to the bounded blocking queue. TCP connections exceeding the bound of the queue will be dropped allowing the accepted connections to operate with a desirable and predictable latency.

Event-Driven Architecture

Separating threads from connections, event-driven architecture only allows threads to be used for events on specific handlers.

This creative concept allows Reactor Pattern to come out of the shelf and show off. A system built on this architecture consists of event creators and event consumers.

The Reactor Pattern

The reactor pattern is the most popular implementation technique of event-driven architecture for TCP connection handling. In simple terms, it uses a single-threaded event loop, blocking on events and dispatches those events to corresponding handlers.

There is no need for other threads to block on I/O, as long as handlers for events are registered to take care of them. Considering a TCP connection, we can easily refer events to these instances: connected, input-ready, output-ready, timeout, and disconnected.

Reactor pattern decouples the modular application-level code from reusable reactor implementation. To achieve that, the architecture of the reactor pattern consists of two important participants — Reactor and Handlers.

Reactor

A Reactor runs in a separate thread, and it is reacting to the I/O events such as connected, input-ready, output-ready, timeout and disconnected, by dispatching the work to the appropriate registered handler.

Handlers

A Handler performs the actual work or the response that needs to be done with an I/O event. A Reactor responds to I/O events by dispatching the appropriate handler.

“Pattern Languages of Program Design” by Jim Coplien and Douglas C. Schmidt which was published way back in 1995, is one of the books that has explained the Reactor Pattern in detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文