使用递归process.nexttick是否可以使其他进程或线程正常工作? [英] Does use of recursive process.nexttick let other processes or threads work?

查看:90
本文介绍了使用递归process.nexttick是否可以使其他进程或线程正常工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Technically when we execute the following code(recursive process.nexttick), the CPU usage would get to 100% or near. The question is the imagining that I'm running on a machine with one CPU and there's another process of node HTTP server working, how does it affect it?

该线程是否执行递归过程.nexttick完全允许HTTP服务器工作?

Does the thread doing recursive process.nexttick let the HTTP server work at all?

如果我们有两个递归过程线程,那么它们是否都获得了50%的份额?

If we have two threads of recursive process.nexttick, do they both get 50% share?

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

Since I don't know any machine with one core cannot try it. And since my understanding of time sharing of the CPU between threads is limited in this case, I don't how should try it with machines that have 4 cores of CPU.

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

谢谢

推荐答案

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

To understand whats going on here, you have to understand a few things about node's event loop as well as the OS and CPU.

首先,让我们更好地理解此代码.您称其为递归,但是吗?

First of all, lets understand this code better. You call this recursive, but is it?

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

In recursion we normally think of nested call stacks and then when the computation is done (reaching a base case), the stack "unwinds" back to the point of where our recursive function was called.

虽然这是一种自行调用(通过回调间接地)的方法,但事件循环使实际发生的事情发生了偏差.

While this is a method that calls itself (indirectly through a callback), the event loop skews what is actually going on.

process.nextTick接受一个函数作为回调,并将其放在事件循环的下一个循环中要完成的工作清单中.然后执行该回调,完成后,您将再次注册相同的回调.从本质上讲,此递归与真正递归之间的关键区别在于,我们的调用堆栈永远不会超过一个调用深度.我们从不放松"堆栈,我们只是连续有很多小的短堆栈.

process.nextTick takes a function as a callback and puts it first at the list of stuff to be done on the next go-around of the event loop. This callback is then executed and when it is done, you once again register the same callback. Essentially, the key difference between this and true recursion is that our call stack never gets more than one call deep. We never "unwind" the stack, we just have lots of small short stacks in succession.

好的,为什么这很重要?

Okay, so why does this matter?

当我们更好地了解事件循环以及实际情况时,我们可以更好地了解系统资源的使用方式.通过以这种方式使用process.nextTick,您可以确保在事件循环中总有事情要做,这就是为什么您会获得较高的CPU使用率(但您已经知道这一点)的原因.现在,如果我们假设您的HTTP服务器将在SAME进程中作为脚本运行,例如下面的

When we understand the event loop better and what is really going on, we can better understand how system resources are used. By using process.nextTick in this fashion, you are assuring there is ALWAYS something to do on the event loop, which is why you get high cpu usage (but you knew that already). Now, if we were to suppose that your HTTP server were to run in the SAME process as the script, such as below

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

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

http.createServer(function (req, res) {
 doHTTPStuff()
}).listen(1337, "127.0.0.1");

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

then how does the CPU usage get split up between the two different parts of the program? Well thats hard to say, but if we understand the event loop, we can at least guess.

由于我们使用process.nextTick,因此doIntervalStuff函数将在事件循环的开始"处每次运行,但是,如果要对HTTP服务器执行某些操作(例如处理连接),那么我们知道它将在下一次事件循环开始之前完成,并且请记住,由于节点的事件性质,它可以在事件循环的一次迭代中处理任意数量的连接.这意味着,至少在理论上,进程中的每个函数都获得了CPU使用率所需要的东西,然后process.nextTick函数使用其余的函数.尽管这并非完全正确(例如,您的阻塞代码会弄乱这一点),但它是一个足以考虑的模型.

Since we use process.nextTick, the doIntervalStuff function will be run every time at the "start" of the event loop, however, if there is something to be done for the HTTP server (like handle a connection) then we know that will get done before the next time the event loop starts, and remember, due to the evented nature of node, this could be handling any number of connections on one iteration of the event loop. What this implies, is that at least in theory, each function in the process gets what it "needs" as far as CPU usage, and then the process.nextTick functions uses the rest. While this isn't exactly true (for example, your bit of blocking code would mess this up), it is a good enough model to think about.

好了,现在(最后)问您真正的问题,那么单独的流程又如何呢?

Okay now (finally) on to your real question, what about separate processes?

有趣的是,操作系统和CPU通常在本质上也很重要".每当进程想要做某事时(例如,在节点的情况下,启动事件循环的迭代),它都会向OS发出要处理的请求,然后OS将该作业推入就绪队列中(优先级高)它在CPU调度程序决定解决该问题时执行.这再次是一个过于简化的模型,但是要取消的核心概念是类似于节点的事件循环,每个进程都获得了它需要"的东西,然后像您的节点应用程序这样的进程尝试通过填写以下内容来尝试执行差距.

Interestingly enough, the OS and CPU are often times also very "evented" in nature. Whenever a processes wants to do something (like in the case of node, start an iteration of the event loop), it makes a request to the OS to be handled, the OS then shoves this job in a ready queue (which is prioritized) and it executes when the CPU scheduler decides to get around to it. This is once again is an oversimplified model, but the core concept to take away is that much like in node's event loop, each process gets what it "needs" and then a process like your node app tries to execute whenever possible by filling in the gaps.

因此,当您的节点进程说它占用了100%的cpu时,这是不准确的,否则,将一事无成,并且系统将崩溃.从本质上讲,它占用了所有可以使用的CPU,但OS仍然决定要插入其他东西.

So when your node processes says its taking 100% of cpu, that isn't accurate, otherwise, nothing else would ever be getting done and the system would crash. Essentially, its taking up all the CPU it can but the OS still determines other stuff to slip in.

如果要添加执行相同过程的第二个节点进程.nextTick,则操作系统将尝试容纳两个进程,并且根据每个节点进程的事件循环上要完成的工作量,操作系统将拆分相应地提高工作效率(至少从理论上讲,但实际上可能会导致一切变慢和系统不稳定).

If you were to add a second node process that did the same process.nextTick, the OS would try to accommodate both processes and, depending on the amount of work to be done on each node process's event loop, the OS would split up the work accordingly (at least in theory, but in reality would probably just lead to everything slowing down and system instability).

再一次,这是非常简单的,但是希望它可以使您对正在发生的事情有所了解.话虽这么说,否则我不建议您使用process.nextTick,除非您知道需要使用它,如果每隔5毫秒执行一次操作是可以接受的,则使用setTimeout代替process.nextTick可以节省CPU使用率.

Once again, this is very oversimplified, but hopefully it gives you an idea of what is going on. That being said, I wouldn't recommend using process.nextTick unless you know you need it, if doing something every 5 ms is acceptable, using a setTimeout instead of process.nextTick will save oodles on cpu usage.

希望能回答您的问题:D

Hope that answers your question :D

这篇关于使用递归process.nexttick是否可以使其他进程或线程正常工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆