Node Js 是否使用 libuv 线程池进行网络 I/O

Cur*_*ous 7 node.js libuv

我在学习Node.js

\n\n

我在 libuv 官方文档中找到了这个注释 -

\n\n

\xe2\x80\x9clibuv使用 athread pool使asynchronous file I/O操作成为可能,但是network I/O始终在单个线程中执行,每个循环\xe2\x80\x99s 线程。\xe2\x80\x9d

\n\n

我的问题是针对以下声明(来自非官方资源)-

\n\n
\n

“如今\xe2\x80\x99s操作系统已经为许多I/O任务提供了异步接口(例如Linux上的AIO)。只要有可能,libuv就会使用这些异步接口,从而避免使用线程池。”

\n
\n\n

-- 此语句对于异步是否正确file I/O operations,或者仅适用于Network I/O

\n\n
    \n
  1. 意味着如果有文件 I/O 操作,那么在这种情况下将强制使用线程池,或者 libuv 将使用那些异步接口,避免使用线程池?
  2. \n
  3. Libuv 是否使用线程池进行网络 I/O ?
  4. \n
\n

Yil*_*maz 6

对于某些标准库函数调用,节点 C++ 端和 libuv 决定完全在事件循环之外进行昂贵的计算。他们制作了一种称为线程池的东西,该线程池是一系列四个线程,可用于运行计算密集型任务例如散列函数或读取硬盘中的文件(fs 模块函数)。只有四种东西使用线程池:DNS 查找、fs、crypto 和 zlib。

因此,正如节点标准库有一些使用 libuv 线程池的函数一样,它也有一些使用通过 libuv 内置到底层操作系统中的代码的函数。libuv 和 Node 都没有任何代码来处理所有这些低级网络请求操作。相反,libuv 将请求委托给底层操作系统。所以实际上是我们的操作系统执行真正的网络请求。Libuv 用于发出请求,然后它只是等待操作系统发出一个信号,表明该请求已得到某些响应。网络 I/O 由系统中的网络硬件完成,ISP.OS 只是不断跟踪连接,一旦 I/O 操作完成,操作系统会将结果传递给 Libuv。


Ari*_*rty 3

我最近迷上了 NodeJS 内部结构以及 V8、D8 和 libuv 之类的东西。因此,真正奇怪的事情之一是网络 I/O 由事件循环处理。但dns.lookup()由 libuv 线程池处理。

因此,仅当您提供url 时,http.get/http.post才会由事件循环处理。IP不是主机名。如果提供了主机名,那么它将在内部使用dns.lookup,这将使操作由线程池处理。

请参阅:IBM 的 Sam Roberts 所著的 Node's Event Loop From the Inside Out

注意:我仍在学习这一点,因此欢迎任何编辑。

  • 无论“ip”或“hostname”如何,“http”始终由事件循环处理。一旦“dns.lookup()”通过线程池完成解析,生成的“dns.resolve”就会在事件循环中运行,进而导致http调用通过操作系统内部(例如“epoll”、“kqueue”等)运行异步 (3认同)