是否使用递归process.nexttick让其他进程或线程工作?

Far*_*hat 5 process cpu-usage multiprocessing node.js

从技术上讲,当我们执行以下代码(recursive process.nexttick)时,CPU使用率将达到100%或接近.问题是想象我在一台带有一个CPU的机器上运行,并且还有另一个节点HTTP服务器工作的过程,它如何影响它?

该线程是否正在进行递归process.nexttick让HTTP服务器工作?

如果我们有两个递归process.nexttick的线程,他们都获得50%的份额?

由于我不知道任何一个核心的机器都无法尝试.而且由于我对线程之间CPU的时间共享的理解在这种情况下是有限的,我不应该如何尝试使用具有4核CPU的机器.

function interval(){
  process.nextTick(function(){
    someSmallSyncCode();
    interval();  
  })
} 
Run Code Online (Sandbox Code Playgroud)

谢谢

add*_*onj 13

要了解这里发生的事情,您必须了解有关节点的事件循环以及操作系统和CPU的一些信息.

首先,让我们更好地理解这些代码.你称之为递归,但是它呢?

在递归中,我们通常会想到嵌套的调用堆栈,然后当计算完成时(达到基本情况),堆栈"展开"回到我们的递归函数被调用的位置.

虽然这是一种调用自身的方法(间接通过回调),但事件循环会扭曲实际发生的事情.

process.nextTick将一个函数作为一个回调函数,并将它放在事件循环下一次复制时要完成的事情列表中.然后执行此回调,完成后,再次注册相同的回调.本质上,这个和真正的递归之间的关键区别在于我们的调用堆栈永远不会有多个调用深度.我们从来没有"放松"堆栈,我们只是连续有很多小的短筹码.

好的,为什么这很重要?

当我们更好地理解事件循环以及真正发生的事情时,我们可以更好地理解系统资源的使用方式.通过以这种方式使用process.nextTick,您可以确保在事件循环中始终可以执行某些操作,这就是您获得高CPU使用率的原因(但您已经知道了).现在,如果我们假设你的HTTP服务器作为脚本在SAME进程中运行,如下所示

function interval(){
  process.nextTick(doIntervalStuff) 
}

function doIntervalStuff() {
  someSmallSyncCode();
  interval();
}

http.createServer(function (req, res) {
 doHTTPStuff()
}).listen(1337, "127.0.0.1");
Run Code Online (Sandbox Code Playgroud)

那么CPU使用情况如何在程序的两个不同部分之间分开?那很难说,但如果我们了解事件循环,我们至少可以猜测.

由于我们使用process.nextTick,doIntervalStuff函数将每次在事件循环的"开始"运行,但是,如果要为HTTP服务器做某事(比如处理连接),那么我们就知道会得到在下一次事件循环开始之前完成,并记住,由于节点的事件性质,这可以在事件循环的一次迭代中处理任意数量的连接.这意味着,至少在理论上,过程中的每个函数都获得了CPU使用所需的"需求",然后process.nextTick函数使用其余函数.虽然这不完全正确(例如,你的一些阻塞代码会搞砸了),但这是一个值得考虑的好模型.

好了,现在(最后)回答你真正的问题,那么单独的流程呢?

有趣的是,操作系统和CPU通常也非常"天".每当进程想要做某事时(比如在节点的情况下,启动事件循环的迭代),它就会向操作系统发出请求,然后操作系统将此作业推送到就绪队列(优先级)它在CPU调度程序决定绕过它时执行.这又是一个过于简化的模型,但要带走的核心概念就像在节点的事件循环中一样,每个进程都获得它"需要"的东西,然后像节点应用程序这样的进程尝试通过填写差距.

因此,当您的节点进程表示它占用了100%的cpu时,这是不准确的,否则,没有其他任何东西可以完成,系统会崩溃.从本质上讲,它可以占用所有CPU,但操作系统仍然可以确定其他内容.

如果您要添加执行相同process.nextTick的第二个节点进程,操作系统将尝试适应这两个进程,并且根据每个节点进程的事件循环要完成的工作量,操作系统会分离工作因此(至少在理论上,但实际上可能只会导致一切变慢和系统不稳定).

再次,这是非常简单的,但希望它能让您了解正在发生的事情.话虽这么说,我不建议使用process.nextTick,除非你知道你需要它,如果每5毫秒做一次是可以接受的,使用setTimeout而不是process.nextTick将节省大量的cpu使用.

希望能回答你的问题:D