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

How*_*ard 73 events design-patterns twisted eventmachine

来自维基百科Reactor Pattern文章:

反应器设计模式是用于处理通过一个或多个输入同时传递给服务处理器的服务请求的事件处理模式.

它命名了几个例子,例如nodejs,twisted,eventmachine

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

如何区分这两个?或者他们是一样的?

Jea*_*one 125

反应器模式比"事件驱动编程"更具体.它是在进行事件驱动编程时使用的特定实现技术.但是,这个术语在典型的对话中并没有得到很好的准确使用,所以你应该小心使用它并期望你的听众理解你,你在使用它时应该小心你如何解释这个术语.

查看反应堆模式的一种方法是将其视为与"非阻塞"操作的概念密切相关.当某些操作可以无阻塞地完成时,反应器会发出通知.例如,select(2)可用于实施反应器图案用于读取和使用标准的BSD套接字API的(写入到插座recv(2),send(2)等). select会告诉你何时可以立即从套接字接收字节 - 例如,因为字节存在于该套接字的内核接收缓冲区中.

在考虑这些想法时,您可能想要考虑的另一种模式是前驱模式.与反应器模式相反,前驱模式具有操作开始,无论它们是否能够立即完成,是否异步执行,然后安排发送有关其完成的通知.

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

这种启动操作然后在完成操作时得到通知的方法是异步操作的核心.将其与非阻塞操作进行比较,在操作中等待操作可以在尝试执行操作之前立即完成.

这两种方法都可用于事件驱动编程.使用reactor模式,程序等待(例如)套接字可读的事件,然后从中读取.使用proactor模式,程序将等待套接字读取完成的事件.

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

  • re 2:select(2)级别很低且难以使用.对于大量事件源来说,它也是低效的.现代平台已超越它,提供等效但更有效的API(/ dev/poll,epoll,kqueue等).libevent(或Twisted)的一个优点是所有这些不同机制的抽象,因此应用程序可以写入统一的API,同时仍然可以从运行时平台上可用的最有效的API中受益.此外还有协议实现形式的明显附加功能,用于管理异步的高级API等. (4认同)

小智 6

我认为这种分离"非阻塞"和"异步"是错误的,因为"异步"的主要含义是"非阻塞".Reactor模式是关于异步(非阻塞)调用,但是同步(阻塞)处理这些调用.Proactor是关于这些调用的异步(非阻塞)调用和异步(非阻塞)处理.