Node.js 使用recursive process.nexttick是否允许其他进程或线程工作?

Node.js 使用recursive process.nexttick是否允许其他进程或线程工作?,node.js,process,multiprocessing,cpu-usage,Node.js,Process,Multiprocessing,Cpu Usage,从技术上讲,当我们执行以下代码(recursive process.nexttick)时,CPU使用率将达到100%或接近100%。问题是,假设我在一台只有一个CPU的机器上运行,而节点HTTP服务器的另一个进程正在工作,这会对它产生什么影响 执行recursive process.nexttick的线程是否允许HTTP服务器工作 如果我们有两个recursive process.nexttick线程,它们是否都得到了50%的份额 因为我不知道任何一台只有一个内核的机器都不能尝试。由于我对线程间

从技术上讲,当我们执行以下代码(recursive process.nexttick)时,CPU使用率将达到100%或接近100%。问题是,假设我在一台只有一个CPU的机器上运行,而节点HTTP服务器的另一个进程正在工作,这会对它产生什么影响

执行recursive process.nexttick的线程是否允许HTTP服务器工作


如果我们有两个recursive process.nexttick线程,它们是否都得到了50%的份额

因为我不知道任何一台只有一个内核的机器都不能尝试。由于我对线程间CPU分时的理解在这种情况下是有限的,所以我不知道如何在有4个CPU核的机器上尝试

function interval(){
  process.nextTick(function(){
    someSmallSyncCode();
    interval();  
  })
} 

谢谢

不。你不必人为地暂停你的进程,让其他人完成他们的工作,你的操作系统有相应的机制。事实上,以这种方式使用
process.nextTick
会降低计算机的速度,因为它有很多开销。

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

首先,让我们更好地理解这段代码。你称之为递归,但它是吗

在递归中,我们通常认为是嵌套的调用堆栈,然后当计算完成时(到达基本情况),堆栈“展开”回到调用递归函数的位置

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

nextTick将函数作为回调函数,并将其放在事件循环下一次循环时要执行的任务列表的第一位。然后执行此回调,完成后,再次注册相同的回调。本质上,这种递归与真正的递归之间的关键区别在于,我们的调用堆栈永远不会有超过一个调用深度。我们从不“展开”堆栈,我们只是连续地有许多小的短堆栈

好吧,为什么这很重要

当我们更好地理解事件循环和真正发生的事情时,我们就能更好地理解系统资源是如何使用的。通过以这种方式使用process.nextTick,您可以确保在事件循环中始终有一些事情要做,这就是为什么cpu使用率很高的原因(但您已经知道这一点)。现在,如果我们假设您的HTTP服务器将在与脚本相同的进程中运行,如下所示

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

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

http.createServer(function (req, res) {
 doHTTPStuff()
}).listen(1337, "127.0.0.1");
那么CPU的使用是如何在程序的两个不同部分之间分配的呢?这很难说,但如果我们了解事件循环,我们至少可以猜测

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

好的,现在(最后)谈谈你真正的问题,关于单独的过程呢

有趣的是,操作系统和CPU在本质上往往也是非常“事件化”的。每当一个进程想要做某事(比如在节点的情况下,启动事件循环的迭代)时,它向操作系统发出一个要处理的请求,然后操作系统将这个作业推到一个就绪队列中(这是有优先级的),并在CPU调度程序决定处理它时执行。这又是一个过于简化的模型,但需要去掉的核心概念非常类似于节点的事件循环,每个进程都会得到它“需要”的东西,然后像您的节点应用程序这样的进程会尽可能通过填补空白来执行

因此,当您的节点进程表示它占用100%的cpu时,这是不准确的,否则,将无法完成任何其他操作,系统将崩溃。从本质上讲,它占用了所有它能占用的CPU,但操作系统仍然决定了其他需要插入的东西

如果要添加执行相同进程的第二个节点进程。nextTick,操作系统将尝试容纳这两个进程,并且根据每个节点进程的事件循环上要完成的工作量,操作系统将相应地拆分工作(至少在理论上,但在现实中可能只会导致一切放缓和系统不稳定)

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


希望这能回答你的问题:D

节点没有线程。你是说完全分离的进程还是发生在同一个节点实例中的事情?不,我说的是节点的两个独立进程,而不是同一个实例。编辑,将线程更改为进程。如果我们有两个递归进程的线程。下一步,它们都得到50%的sha吗阿尔弗雷德恩斯:关于召唤,但不是关于时间。