标题基本上说明了一切,当我们可以更改 libuv 线程池使用的线程数时,为什么还要创建节点工作程序?
该libuv
线程池不用于JavaScript代码,仅用于Node.js的的API的一个子集(虽然它使用的最重要的人之一,fs
)。从文档:
Node.js 会尽可能使用异步系统 API,但在它们不存在的情况下,
libuv
的线程池用于创建基于同步系统 API 的异步节点 API。使用线程池的 Node.js API 有:
- 所有
fs
API,除了文件观察器 API 和那些显式同步的 API- 异步加密 API,例如
crypto.pbkdf2()
,crypto.scrypt()
,crypto.randomBytes()
,crypto.randomFill()
,crypto.generateKeyPair()
dns.lookup()
- 所有
zlib
API,显式同步的 API 除外
因此libuv
线程池的大小有助于处理大量重叠fs
和相似的调用,但这并不是全部。
libuv
如果您有需要同步完成大量工作的 JavaScript 代码,该池将无济于事;该代码在单个线程上运行(除非您启动工作程序)。此外,Node.js 使用同一个线程来检查异步工作的libuv
完成(包括完成)。从事件循环页面:
下图显示了事件循环操作顺序的简化概述。
┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ close callbacks │ └───────────────────────────┘
这样即使没有运行您的 JavaScript 代码,一个线程也会做很多工作。
如果您启动工作线程,它们每个都有自己的事件循环,并且可以处理与其工作相关的完成,即使另一个线程正忙于执行占用大量 CPU 的工作。
因此,工作线程在任何给定情况下是否有用在很大程度上取决于您的代码在做什么。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句