19

I am trying to understand how concurrency works in a single-threaded environment like nodejs.

Let's say I have this code:

var fs = require('fs');

fs.readFile('file1', function one(err, data) {
  // some code...
});

fs.readFile('/file2', function two(err, data) {
  // some code...
});

Now each fs.readFile call is async. So, they are running concurrently. But if all this is happening in a single thread, then how is the concurrency achieved? Are function one and function two running on the same or different thread?

Basically, how does node.js handle concurrency?

victorkt
  • 13,992
  • 9
  • 52
  • 51
Jatin
  • 14,112
  • 16
  • 49
  • 78
  • 1
    http://stackoverflow.com/q/14795145/438992 – Dave Newton Apr 30 '15 at 20:27
  • 2
    This answer is written for a browser, but the same principle applies in node.js: [How does JavaScript handle AJAX responses in the background?](http://stackoverflow.com/questions/7575589/how-does-javascript-handle-ajax-responses-in-the-background/7575649#7575649) In other words, node.js works similarly based on an event queue and native code that is likely using other threads, but all activity in Javascript itself is synchronized to one thread via an event queue. – jfriend00 Apr 30 '15 at 21:37

3 Answers3

20

As far as Node is concerned, there is only one thread. Asynchronous calls are put into the event queue and only run on the next tick.

For code that Node passes off to C++, all bets are off. There might or might not be threads there. But it doesn't really affect you.

The explanation that has been the most effective for me is "What the heck is the event loop anyway?" by Philip Roberts because the slow-motion visualization tool he shows makes everything pretty clear (to me, anyway).

You can experiment with Philip's tool Loupe online.

Trott
  • 66,479
  • 23
  • 173
  • 212
10

The thing with node.js is that everything runs concurrently, except for your code.

So, what that means is that there are actually lots of threads running inside node.js virtual machine (or a thread pool if you wish), and those threads are utilized whenever you call an async function like performing i/o operations on files, accessing databases, requesting urls, etc.

However, for your code, there is only a single thread, and it processes events from an event queue. So, when you register a callback it's reference is actually passed to the background worker-thread, and once the async operation is done, new event is added to the event-queue with that callback.

npe
  • 15,395
  • 1
  • 56
  • 55
  • So, essentially, in the code I provided file1 and file2 are being read on separate threads? – Jatin Apr 30 '15 at 20:34
  • 2
    While it's possible that the same worker-thread will be assigned with both tasks, it should be considered rather unlikely. But it's definitely a worker-thread who reads those files, and not your event-loop-thread. – npe Apr 30 '15 at 20:36
8

Node.js does use multiple threads to handle io user the covers, but this is hidden from the user. The application environment (ie. your code) only has access to a single thread, but Node.js transparently hands off the io to a separate thread without the user needing to deal with it.

In your case, function one and two are both running in the same thread, but the actual io operations to read the file data were performed in separate threads.

A more detailed description of Node.js's threading/io model can be found here and a nice set of analogous examples can be read here.

Steve U
  • 326
  • 2
  • 7