11

今天早些时候,我用这个答案回答了一个问题。在我发布的示例中,我在 bcrypt 节点模块中使用了同步版本的调用。我选择使用同步版本的调用主要是因为我认为它使响应看起来更清晰,但我也不认为它会影响性能,因为 bcrypt 是 cpu 和内存密集型而不是 I/O 绑定。据我了解,node 几乎像浏览器一样在单个线程上运行您的所有代码,并且只将后台线程用于 I/O 和数据库访问等事情。这让我相信 CPU 密集型任务本质上仍然会“阻塞”服务器,因为没有其他线程可以卸载工作。

对我的回复的评论表明我的假设是错误的,经过一些研究,我意识到我并没有真正了解 node.js 如何处理这类事情。node.js 中的异步编程是否会加速 CPU 和内存密集型调用?如果是这样,它是如何做到的?

4

1 回答 1

10

这取决于模块的实现方式。

如果模块是在不支持线程的情况下实现的,那么是的,CPU 绑定处理不能异步完成。有些函数提供回调并且我看起来是异步的,但实际上并非如此。它们实际上是同步运行并阻塞事件循环。javascript 中的示例是Array.forEach().

但是,可以实现模块以在后台线程中进行处理。在这种情况下,它确实是异步的,可以加速 CPU 密集型任务。至少它释放了事件循环以在后台线程忙于计算结果时处理传入的请求。

这方面的一个例子是crypto.pbkdf2()节点自己的 Crypto 模块中的函数。

但是,当 node.js 在单线程中运行时,模块如何在其他线程中执行代码呢?

最初的实现方式很简单,该模块不是用 javascript 编写的,而是用 C/C++ 编写的,并通过它的插件 API 与 node.js 接口。

但是现在,即使是纯 javascript 模块和函数也可以产生线程和/或进程。Node 有一个名为 Cluster 的实验模块,用于设置节点进程的主/从集群。然后,您的模块或代码可以在工作进程中运行 CPU 绑定任务,从而释放主节点进程来处理事件循环。npm 上还有几个线程模块可用。只需在 npmjs.org 上搜索“线程”。

所以,是的,CPU 绑定的任务可以运行得更快,或者至少不会通过异步运行来阻塞主事件循环。

于 2013-06-20T04:38:25.483 回答