node.js/libuv如何使用reactor模式支持异步io

node.js/libuv如何使用reactor模式支持异步io,node.js,asynchronous,io,libuv,reactor,Node.js,Asynchronous,Io,Libuv,Reactor,libuv用于处理IO的reactor模式在设计上是同步的,但libuv支持异步IO。这怎么可能?libuv是否以某种方式扩展了反应堆的设计以支持异步io?使用多线程/事件循环是否有助于实现这一点?Node和libuv的I/O模型与nginx内部的工作非常相似 libuv使用一个单线程事件循环和非阻塞异步I/O。所有函数都是同步的,运行到完成为止,但是可以使用一些巧妙的黑客技术,通过承诺和生成器来显示它们不是同步的(实际上,对生成器函数的调用都是非阻塞的,并立即返回生成器对象和生成器方法,如.n

libuv用于处理IO的reactor模式在设计上是同步的,但libuv支持异步IO。这怎么可能?libuv是否以某种方式扩展了反应堆的设计以支持异步io?使用多线程/事件循环是否有助于实现这一点?

Node和libuv的I/O模型与nginx内部的工作非常相似

libuv使用一个单线程事件循环和非阻塞异步I/O。所有函数都是同步的,运行到完成为止,但是可以使用一些巧妙的黑客技术,通过承诺和生成器来显示它们不是同步的(实际上,对生成器函数的调用都是非阻塞的,并立即返回生成器对象和生成器方法,如
.next()
run to completion),再加上新的async/await语法,使用起来非常方便

对于不能以非阻塞方式完成的操作,节点使用线程池在单独的线程中运行阻塞操作,但这是透明的,而且它从不暴露于JavaScript编写的应用程序代码(您需要下移到C++直接处理)。 见:

与网络I/O不同,libuv无法依赖平台特定的文件I/O原语,因此当前的方法是在线程池中运行阻塞文件I/O操作。[…]

libuv当前使用一个全局线程池,所有循环都可以在该线程池上对工作进行排队。此池上当前运行3种类型的操作:

  • 文件系统操作
  • DNS函数(getaddrinfo和getnameinfo)
  • 用户通过uv_队列_工作()指定的代码
有关更多详细信息,请参见这些答案:

  • *

请参阅这些答案中的链接和插图。关于这个主题,有很多参考资料可供阅读。

这些参考资料都很好,但没有一个专门讨论这个问题。让我问一个更具体的问题。由于所有网络io都在libuv内的单个线程上运行,因此要实现异步io(例如,使用读取事件),您需要d必须为操作系统委派任务,并为其提供一个用户定义的缓冲区,该缓冲区将填充来自读取操作的数据,但这将是前置模式。libuv如何通过使用单线程反应器事件循环实现类似效果?@Michael Most网络I/O在单个therad上运行,但不是DNS操作(getaddrinfo和getnameinfo)而不是文件系统I/O,因此这并不像看上去那么清晰,没有一种理论模式可以100%应用于Node需要在所有平台上支持的所有边缘情况。@Michael我在答案中包含的列表中的第一个答案有一些评论,您可能会发现这些评论是由(我想他会给你一个更详细的答案来回答你的评论,但不幸的是,只有在评论中提到某人才可能回答他已经评论过的地方)。