【问题标题】:Does Node.js delegate multithreading?Node.js 是否委托多线程?
【发布时间】:2019-05-10 03:07:38
【问题描述】:

我有一个带有 REST 端点的快速服务器的示例代码,该端点执行 fs.readFile 操作。 我知道该操作是异步的,不会阻塞作为单线程进程运行的主线程。 但是我想澄清一下当有数百个对 Node.js 服务器的请求并且请求在 I/O 中排队时会发生什么。在 I/O 的后台发生的文件读取操作是否有任何类型的多线程等级?或者这也只是一个单线程操作?如果是这样,它不会成为大量请求的瓶颈吗?

【问题讨论】:

标签: node.js express fs


【解决方案1】:

node.js 中的文件 I/O 使用线程池(用于与文件操作关联的本机代码)。有一个用于挂起文件 I/O 操作的队列,线程池中的每个线程从队列中获取一个事件,处理它,完成它,触发完成事件,然后从队列中获取下一个挂起的文件 I/O 操作,然后处理它。

从 Javascript 方面来看,这都是非阻塞的。当您调用其中一个异步文件操作时,它会被移交给文件 I/O 子系统,并立即将控制权返回给 JS 引擎以运行其他 JS。稍后,当内部系统完成文件 I/O 操作,并将事件添加到 node.js 事件队列中,并且当时正在运行的任何 JS 完成并到达 node.js 事件队列中的下一个事件时,然后调用与完成该异步文件操作相关的回调,并运行与之相关的 JS。

我有一个带有执行 fs.readFile 操作的 REST 端点的快速服务器的示例代码。我了解该操作是异步的,不会阻塞作为单线程进程运行的主线程。

没错。

但是我想澄清一下当有数百个请求到 Node.js 服务器并且请求在 I/O 中排队时会发生什么。这里的文件读取操作是否有任何类型的多线程在后台发生输入/输出级别?

数百个请求将堆积在内部文件 I/O 队列中,并且它们将由用于文件 I/O 的内部本机代码的线程池中的 N 个线程一次处理 N 个。

或者这也只是一个单线程操作?如果是这样,它不会成为大量请求的瓶颈吗?

一次是 N 个线程(线程池中的线程数)。是的,这将是一个瓶颈。无论如何编程,同时执行数百个文件请求总是会成为某种瓶颈,因为在最低级别,磁盘一次只能查找一个位置并一次读取磁盘的一部分. node.js 内部的线程池大小是可控的,但是如果你所有的磁盘 I/O 请求都到同一个底层磁盘,你会达到一个地步,通过添加更多的线程来提高效率。争用磁盘上的同一个读/写磁头。

如果您想了解更多关于 node.js 事件循环和其他子系统如何工作的信息,这里有很多关于该主题的有用文章:

How Node.Js Single Thread mechanism Work ? Understanding Event Loop in NodeJs

Handling IO — NodeJS Event Loop Part 4

How node.js event loop works

The Node.js Event Loop, Timers, and process.nextTick()

libuv documentation on the thread pool and customizing it

【讨论】:

  • 这可以概括为:“I/O 在主线程中排队并在主线程之外处理。该队列的具体处理方式取决于操作系统”?
  • @Pranavkirtani - 请确保您已看到我的回答中最近添加的所有内容。我希望您会发现这是对您的问题的一个相当全面的答案,其中包含大量外部参考资料以了解更多信息。如果没有,请告诉我您在理解方面仍需要帮助。
  • @NikKyriakides - 所有类型的 I/O 的处理方式不同。网络 I/O 使用操作系统中的底层异步模型,因此它不使用线程。磁盘 I/O 确实使用 libuv 中的线程池,然后使用底层操作系统执行实际的文件操作。文件 I/O 队列本身在 libuv 中,而不是在操作系统中。是 libuv(node.js 的一部分)从队列中拉出一个项目,将其交给线程池中的一个线程,然后让操作系统处理该线程中的实际文件操作。
  • 谢谢; libuv 不也处理 Node.js 的网络 I/O 吗?
  • @NikKyriakides - 是的。 libuv 是 node.js 使用的操作系统级别抽象的一部分。请参阅docs.libuv.org/en/v1.x/design.html 了解更多信息。
【解决方案2】:

cmets 中的 cloudburst.io 链接是一个很好的深入解释。

简短的版本是节点进程本身是单线程的,但它依赖于操作系统来处理 I/O 任务和类似的任务,通过文件句柄跟踪挂起的回调。

这意味着您的问题的答案是“或多或少”,因为它假定操作系统具有支持功能。大多数都这样做,所以这是一个安全的选择,但并非所有 IO 操作都可以保证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多