Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does use of recursive process.nexttick let other processes or threads work?

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?

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

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

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();  
  })
} 

Thanks

like image 335
Farid Nouri Neshat Avatar asked Nov 13 '11 14:11

Farid Nouri Neshat


People also ask

What does process nextTick do?

Such is a method called process. nextTick() which is used by developers in real-time applications every day to defer the execution of a function until the next Event Loop Iteration.

What is the difference between process nextTick () and setImmediate ()?

1. process. nextTick() is used to schedule a callback function to be invoked in the next iteration of the Event Loop. setImmediate() method is used to execute a function right after the current event loop finishes.

Why do we want sometimes to use setImmediate instead of using setTimeout?

The main advantage to using setImmediate() over setTimeout() is setImmediate() will always be executed before any timers if scheduled within an I/O cycle, independently of how many timers are present.


2 Answers

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 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?

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");

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.

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?

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.

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.

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).

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.

Hope that answers your question :D

like image 62
addisonj Avatar answered Sep 28 '22 05:09

addisonj


No. You don't have to artificially pause your processes to let others do their work, your operating system has mechanisms for that. In fact, using process.nextTick in this way will slow your computer down because it has a lot of overhead.

like image 27
thejh Avatar answered Sep 28 '22 05:09

thejh