为什么节点会产生多个线程?

Why does node spawn several threads?

我列出了我的节点服务器的线程,以下是标准输出上的响应:

$ ps -e -T | grep 14209
14209 14209 ?        00:10:08 node
14209 14415 ?        00:00:00 V8 WorkerThread
14209 14416 ?        00:00:00 V8 WorkerThread
14209 14417 ?        00:00:00 V8 WorkerThread
14209 14418 ?        00:00:00 V8 WorkerThread
14209 14419 ?        00:00:00 node
14209 15894 ?        00:00:00 node
14209 15895 ?        00:00:00 node
14209 15896 ?        00:00:00 node
14209 15902 ?        00:00:00 node

我了解到 nodejs 是单线程的,同一个线程负责处理 javascript 代码。那么,最后五个线程的目的是什么?它们是由处理异步 I/O 的 libuv 生成的吗?

So, what is the purpose of last five threads? Are they spawned by libuv which handles asynchronous I/O?

至少其中一些(如果不是全部)是由于 libuv,是的。
该库有一个线程池(它在 documentation 中明确提到)主要用于 fs 请求,即使不仅仅是它们:

libuv provides a threadpool which can be used to run user code and get notified in the loop thread. This thread pool is internally used to run all file system operations, as well as getaddrinfo and getnameinfo requests.

这是因为 fs 请求之类的东西本质上是同步的,而使它们看起来异步的唯一方法是在单独的线程上生成请求,然后在主线程上处理响应。

话虽这么说,JavaScript 环境确实是单线程的,但它并不强制底层库(主要是 v8libuv)不使用线程在内部为他们的目的。只要 JavaScript 运行时在用户看来是单线程的,就没有理由不使用线程。
实际上,这正是这些库在某种程度上为执行任务和提高性能所做的:它们产生线程并在内部使用它们。