【问题标题】:How does NodeJS handle parallel execution for same functions in a loop?NodeJS 如何处理循环中相同函数的并行执行?
【发布时间】:2019-09-06 16:17:54
【问题描述】:

我正在循环中运行相同的异步函数,而无需在具有 2 个 CPU 的系统中等待该函数。当我从函数内部登录到进程 id 时,它们都具有相同的进程 id,

Node 如何处理这种并行执行?两个 CPU 都在正常使用吗?我是否需要为循环中的每个函数手动 fork 进程?


function next(){
 console.log('main started', process.$
 const arr=[];
  for(let i=0; i<10000000; i++)    
                arr.push(1);
  arr.sort(function(a, b){return a<b});
 console.log('main ended')
}

function main(){
 next();
 next()
 next();
 next();
 next();
 next();
 console.log('-----------------------------$
}

main()


HTOP Screenshot

【问题讨论】:

  • 向我们展示您在循环中的实际代码以及异步操作是什么,我们可以更具体地回答。 node.js 将您的 Javascript 作为单线程运行,但将线程用于一些异步操作(文件 I/O)并使用本机异步支持来支持其他类型的操作(网络),并使用进程来处理诸如 spawn()exec() 之类的事情。向我们展示您实际操作的代码,以便我们解释。
  • 请不要只是发布和消失。这不是stackoverflow的工作方式。当人们与您互动以提供帮助时,如果您在合理的时间内与您互动,您将获得更好的帮助。

标签: javascript node.js asynchronous process


【解决方案1】:

Node.js 在单个线程中运行您的实际 Javascript,因此它不会将多个 CPU 应用于您的实际 Javascript,除非您专门设计代码以将 CPU 密集型任务放在 Worker threads 中,或者您创建自己的单独进程使用集群或使用 child_process 模块来启动您自己的其他进程,然后将工作交给它们。只需运行您的 node.js 程序,CPU 密集型操作(如您的长循环排序)将占用 CPU 并阻止事件循环处理其他请求。它不会涉及其他 CPU 进行排序操作,也不会为您的 Javascript 使用其他 CPU。

当您运行异步操作时,该操作后面会有本机代码,并且本机代码可能使用也可能不使用额外的线程或进程。例如,文件 I/O 使用线程池。网络使用本机操作系统异步支持(无线程)。 spawn()exec() in child_process 启动新进程。

如果您向我们展示您的具体情况的实际代码,我们可以更具体地回答该特定操作的工作原理。

Node 如何处理这种并行执行?

这取决于操作是什么。

两个 CPU 都在正常使用吗?

可能不会,但我们需要查看您的具体代码。

是否需要为循环中的每个函数手动 fork 进程?

视具体情况而定。要将多个 CPU 应用于您的实际 Javascript(不是异步操作),那么您将需要多个进程运行您的 Javascript 或者可能是最新的 Worker 线程 api。如果并行性全部在异步操作中,那么 node.js 的事件驱动特性特别擅长同时管理许多异步操作,您甚至可能无法从涉及多个 CPU 中受益,因为大多数时候所有 node.js 都在做正在等待 I/O 完成,许多请求已经可以在 node.js 中非常有效地同时进行。

为了实际应用多个 CPU 来运行您的 Javascript 本身,node.js 有 clustering module 这是专门为此而构建的。您可以为计算机中的每个实际 CPU 内核启动一个集群进程。或者,您也可以使用新的Worker thread api

另请参阅讨论如何在 node.js 中解决 CPU 密集型代码的这些答案:

How to process huge array of objects in nodejs

How to apply clustering/spawing child process techniques for Node.js application having bouth IO bound and CPU bound tasks?

node.js socket.io server long latency

Is it possible somehow do multithreading in NodeJS?

How cpu intensive is too much for node.js (worried about blocking event loop)

【讨论】:

  • 感谢您的回复。我已经用代码更新了帖子
  • @ZeeshanShamsuddeen - 这不是真正的代码,也没有显示任何真正的异步操作。正如我多次说过的,并行策略取决于特定的异步操作。如果你展示你的实际代码,而不是伪代码,不是理论代码,不是没有代码的理论问题,你总是会在这里得到更好的答案。
  • 抱歉,因为我是 StackOverFlow 的新手。我已经用实际代码编辑了帖子。请看看这个。
  • @ZeeshanShamsuddeen - 这些操作都不是 CPU 密集型或阻塞 Javascript 执行的单线程。 axios 调用只是一个网络请求,在等待响应时完全不使用 CPU。数据库调用也只是对另一个进程(数据库)的网络操作。无需为该循环参与任何其他流程。您的性能将受到目标服务器响应能力的限制,而不是您的 node.js 进程。
  • @jfriend00:谢谢。如果循环计数为 100。这我打 API 100 次并等待它的响应。现在,当所有响应并行返回时,Node 会完美处理这个问题吗?如果需要,Node 会在这段时间内同时使用这两个 CPU 吗?如何理解 Node 可以处理多少这样的并行进程?
【解决方案2】:

您可以使用Promise.all 从这个异步函数返回解析的数据。这样节点就不会等待处理每个数组项。

let results = await Promise.all(
array.map(arrayItem => executeAsynchronousFunctionWith(arrayItem))
);

变量results是一个解析结果数组。

【讨论】:

  • 当使用 Promise.all 和同步代码时,这可能无法正常工作
猜你喜欢
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多