事件驱动模式和反应堆模式有什么区别?
从维基百科反应堆模式文章:
反应堆devise模式是一种事件处理模式,用于处理通过一个或多个input同时传送到服务处理程序的服务请求。
它命名了几个例子,例如nodejs
, twisted
, eventmachine
但是我所知道的上面是stream行的事件驱动框架,那么使它们也成为一个反应器模式框架呢?
如何区分这两个? 或者他们是一样的?
反应堆模式比“事件驱动的编程”更具体。 这是执行事件驱动编程时使用的特定实现技术。 然而,这个术语在典型的谈话中使用得不是很准确,所以你应该小心使用它,期望你的听众能够理解你,而且在你使用这个术语的时候,你应该小心的解释这个术语。
看反应堆模式的一种方法是认为它与“非阻塞”操作的想法密切相关。 当某些操作可以完成而没有阻塞时,反应堆发出通知。 例如, select(2)
可用于实现使用标准BSD套接字API( recv(2)
, send(2)
等)读取和写入套接字的reactor模式。 select
会告诉你什么时候你可以立即从套接字接收字节 – 例如,因为字节出现在那个套接字的内核接收缓冲区中。
在考虑这些想法时,您可能需要考虑的另一个模式是前瞻模式。 与反应堆模式相反,无论是否可以立即完成操作,操作员模式都会启动操作,并使它们asynchronous执行,然后安排提交有关完成的通知。
Windows I / O完成端口(IOCP)API是可以看到前摄器模式的一个示例。 在使用IOCP的套接字上执行发送时,不pipe在该套接字的内核发送缓冲区中是否有空间,都会启动发送操作。 当WSASend
调用立即完成时,发送操作继续(在另一个线程中,也许是内核中的一个线程)。 当发送实际完成时(意味着只发送的字节被复制到该套接字的内核发送缓冲区中),调用WSASend
调用的callback函数(在应用程序的新线程中)。
这种开始操作并在完成时得到通知的方法是asynchronous操作的核心。 将它与非阻塞操作进行比较,您可以在尝试执行操作之前等待操作完成。
任何一种方法都可以用于事件驱动的编程。 使用reactor模式,程序等待(例如)一个套接字的事件可读,然后读取它。 使用前置模式,程序等待套接字读取事件完成。
严格来说,Twisted滥用术语反应堆 。 基于select(2)
( twisted.internet.selectreactor
)的Twisted反应堆是使用非阻塞I / O实现的,这非常类似于反应堆。 但是,它暴露给应用程序代码的接口是asynchronous的 ,使得它更像前摄式。 Twisted还有一个基于IOCP的反应堆。 这个反应器公开了相同的面向asynchronous应用程序的API, 并使用类似于前向器的IOCP API。 这种混合的方法,从细节到平台的不同,使得术语“reactor”和“proactor”都不是特别准确,但是由于twisted.internet.reactor
公开的API基本上是完全asynchronous的而不是非阻塞的, 所以proactor会可能是一个更好的select名称。
我认为这种“非阻塞”和“asynchronous”的分离是错误的,因为“asynchronous”的主要含义是“非阻塞”。 Reactor模式是关于这些调用的asynchronous(非阻塞)调用,但同步(阻塞)处理。 Proactor是关于这些调用的asynchronous(非阻塞)调用和asynchronous(非阻塞)处理。