15

I am learning Node.js and I have read that Node.js is single threaded and non-blocking.

I have a good background in JavaScript and I do understand the callbacks, but what I don't really understand is how Node.js can be single threaded and run code in the background. Isn't that contradictory?

Because if Node.js is single threaded it can still only perform one task at the time. So if it runs something in the background it has to stop the current task to process something in the background, right?

How does that work practically?

foobar
  • 616
  • 2
  • 6
  • 12
Mathieu David
  • 4,706
  • 3
  • 18
  • 28
  • You can learn about the event loop here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop – Felix Kling Apr 28 '15 at 06:11
  • 2
    Though this description of asynchronous background activity is written for a browser, it pretty much works for node.js also (same concept): http://stackoverflow.com/questions/7575589/how-does-javascript-handle-ajax-responses-in-the-background/7575649#7575649. The summary is that background tasks don't run in the one node.js thread. They either run in native threads themselves or they use non-blocking IO themselves and communicate with the one node.js thread via an event queue. – jfriend00 Apr 28 '15 at 06:33

4 Answers4

10

What "in the background" really means in terms of NodeJS is that things get put on a todo list for later. Whenever Node is done with what it's doing it picks from the top of the todo list. This is why doing anything that actually IS blocking can wreck your day. Everything that's happening "in the background" (actually just waiting on the todo list) gets stopped until the blocking task is complete.

Lucas
  • 193
  • 1
  • 6
  • As Alexis notes, NodeJS can actually take advantage of more than one thread via libraries or the [Cluster Class](https://nodejs.org/api/cluster.html). But its important to understand that this lets you spin up multiple copies of a given Node process. Each of them individually will still act like a single threaded program. – Lucas Apr 28 '15 at 06:41
  • Ok that clarifies some things, so if I would call a blocking function that has a callback to a second blocking function. That would be kind of the same as if it was procedural ? ( and to be avoided? ) – Mathieu David Apr 28 '15 at 06:58
  • That's not what "in the background" means. See my answer. – OrangeDog Apr 28 '15 at 10:10
4

Lucas explained it well, but I would like to add, this is possible to add "nodes" via some cluster libraries if you want to take advantage of your processors.

A tutorial to do a cluster: http://blog.carbonfive.com/2014/02/28/taking-advantage-of-multi-processor-environments-in-node-js/

Some hosters will give your the 'scalability' options, like Heroku

Anyway, when you use MongoDB with NodeJS (via Mongoose for example), it creates multiples connections.

NOTE: The advantage to be monothreaded is to handle millions users. With a legacy multithreaded server (apache), you create a thread for EACH user, then you need really BIG servers to handle thousands people.

Alexis Paques
  • 1,885
  • 15
  • 29
2

While the JavaScript engine is monothreaded, there are multiple threads "in the background" that deal with all the non-blocking I/O work.

Specifically, libuv has a pool of worker threads waiting on OS events, I/O signals, running C++ code, etc. Size of this pool is determined by the UV_THREADPOOL_SIZE environment variable.

No JavaScript code ever runs "in the background". JavaScript functions (i.e. callbacks) are scheduled to run later on the main event loop, either by other JS functions or directly by the libuv workers. If the loop is blocked, then everything scheduled has to wait for it.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
0

In fact, Node.js is not exactly monothreaded. Node.js use one "main thread", which is the thread where you script is executed. This main thread must never be blocked. So long-running operations are executed in separate threads. For example, Node.js use libuv library which maintains a pool of threads used to perform I/O.

user3085414
  • 122
  • 2