【发布时间】:2021-03-13 08:08:22
【问题描述】:
标题基本上说明了一切,既然我们可以更改 libuv 线程池使用的线程数,为什么还要创建节点工作器?
【问题讨论】:
标签: javascript node.js multithreading multiprocessing libuv
标题基本上说明了一切,既然我们可以更改 libuv 线程池使用的线程数,为什么还要创建节点工作器?
【问题讨论】:
标签: javascript node.js multithreading multiprocessing libuv
libuv 线程池不用于您的 JavaScript 代码,仅用于 Node.js 的 API 子集(尽管它被最主要的 API 之一使用,fs)。来自the documentation:
Node.js 尽可能使用异步系统 API,但在它们不存在的地方,
libuv的线程池用于基于同步系统 API 创建异步节点 API。使用线程池的 Node.js API 有:
- 所有
fsAPI,文件观察程序 API 和显式同步的 API 除外- 异步加密API,例如
crypto.pbkdf2()、crypto.scrypt()、crypto.randomBytes()、crypto.randomFill()、crypto.generateKeyPair()dns.lookup()- 所有
zlibAPI,显式同步的 API 除外
所以libuv 线程池的大小有助于处理大量重叠的fs 和类似调用,但这并不是全部。
如果您的 JavaScript 代码需要同步执行大量工作,libuv 池对您没有帮助;该代码在单个线程上运行(除非您启动工人)。此外,Node.js 使用同一线程来检查异步工作的完成情况(包括 libuv 完成情况)。来自event loop page:
下图显示了事件循环操作顺序的简化概览。
┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ close callbacks │ └───────────────────────────┘
这样一个线程即使在不运行 JavaScript 代码时也能做很多工作。
如果您启动工作线程,它们每个都有自己的事件循环,并且可以处理与其工作相关的完成,即使另一个线程正忙于做一些 CPU 密集型的事情。
因此,工作线程在任何给定情况下是否有用很大程度上取决于您的代码在做什么。
【讨论】: