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

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

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

它命名了几个例子,如 nodejstwistedeventmachine

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

如何区分这两者? 还是它们是一样的?

26780 次浏览

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

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

在考虑这些想法时,您可能需要考虑的另一种模式是 监督员模式。与反应堆模式相反,前处理程序模式有操作开始,不管它们是否能立即完成,有它们执行 异步的,然后安排发送关于它们完成的通知。

Windows I/O Completion Ports (IOCP) API 是可以看到 监督员模式的一个示例。当使用 IOCP 对套接字执行发送时,发送操作将启动,而不管内核发送缓冲区中是否有空间用于该套接字。发送操作继续(在另一个线程中,可能是内核中的一个线程) ,同时 WSASend调用立即完成。当发送 事实上完成时(意味着只有被发送的字节被复制到该套接字的内核发送缓冲区中) ,将调用提供给 WSASend调用的回调函数(在应用程序中的新线程中)。

这种启动操作然后在操作完成时被通知的方法是 异步的操作思想的核心。将其与 无阻塞操作进行比较,在 无阻塞操作中,您要等到某个操作可以立即完成后再尝试执行该操作。

这两种方法都可以用于事件驱动编程。使用反应器模式,程序等待(例如)套接字的 事件是可读的,然后从中读取。使用前置程序模式,程序将等待套接字读取完成的 事件

严格地说,扭曲误用术语 反应堆。基于 select(2)(twisted.internet.selectreactor)的扭曲反应器采用非阻塞 I/O 实现,非常类似于反应器。但是,它向应用程序代码公开的接口是 异步的,使其更像前处理程序。Twsted 还有一个基于 IOCP 的反应堆。这个反应器公开了相同的面向异步应用程序的 API 还有使用类似前处理程序的 IOCP API。这种混合方法,在细节上因平台而异,使得术语“反应器”和“前处理器”都不是特别准确,但是由于 twisted.internet.reactor暴露的 API 基本上是完全异步的,而不是非阻塞的,因此 监督员可能是一个更好的名字选择。

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

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

基于线程的体系结构

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

调度程序在 TCP 套接字上阻塞新连接,并将它们提供给有界阻塞队列。超过队列边界的 TCP 连接将被删除,允许接受的连接以期望的和可预测的延迟进行操作。

事件驱动架构

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

这个创造性的概念允许反应堆模式走出货架和炫耀。基于此体系结构构建的系统由事件创建者和事件使用者组成。

反应堆模式

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

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

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

反应堆

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

负责人

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

Jim Coplien 和 Douglas C. Schmidt 在1995年出版的《程序设计的模式语言》是详细解释反应堆模式的著作之一。