15

Node.js maintains an event loop but then it also has by default four threads for the complicated requests. How this is single threaded when there are more threads available in the thread pool?

Also, the threads assigned by the event loop for the complicated task are the dedicated threads then how it's different from other multithreading concepts?

Mika Sundland
  • 18,120
  • 16
  • 38
  • 50
rahul kumar
  • 151
  • 1
  • 5
  • 1
    It is not thread. They are child processes. Child process, process and threads are different things. – Nidhin David Jan 13 '18 at 15:29
  • so event loop is the only one thread and if any blocking I/O then it's taken care by the Child Process!! am i correct ? can you help me with some link where i can read this properly ?? thanks :) – rahul kumar Jan 13 '18 at 16:20
  • As a sidenote, if you like concurrent programming then checkout Go programmiing language. It is concurrent as well as real multithreaded but compiled and statically typed as well. https://www.golang-book.com/books/intro/10 – Nidhin David Jan 14 '18 at 03:48
  • I misread your question. I wasn't talking about the internal threads maintaiend by Node.js. I was talking about forked processes. https://nodejs.org/dist/latest-v8.x/docs/api/cluster.html#cluster_cluster and https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_child_process – Nidhin David Jan 14 '18 at 03:54
  • duplicate Why is Node.js single threaded? [closed] - Stack Overflowhttps://stackoverflow.com › questions › why-is-node-js-... – mercury Nov 29 '21 at 20:41

4 Answers4

16

In the context to which you're referring, "single threaded" means that your Javascript runs as a single thread. No two pieces of Javascript are ever running at the same time either literally or time sliced (note: as of 2020 node.js does now have WorkerThreads, but those are something different from this original discussion). This massively simplifies Javascript development because there is no need to do thread synchronization for Javascript variables which are shared between different pieces of Javascript because only one piece of Javascript can ever be running at the same time.

All that said, node.js does use threads internal to its implementation. The default four threads you mention are used in a thread pool for disk I/O. Because disk I/O is normally a synchronous operation at the OS level that blocks the calling thread and node.js has a design where all I/O operations should be offered as asynchronous operations, the node.js designers decided to fulfill the asynchronous interface by using a pool of threads in order to implement (in native code), the fs module disk I/O interface (yes there are non-blocking disk I/O operations in some operating systems, but the node.js designers decided not to use them). This all happens under the covers in native code and does not affect the fact that your Javascript runs only in a single thread.

Here's a summary of how a disk I/O call works in node.js. Let's assume there's already an open file handle.

  1. Javascript code calls fs.write() on an existing file handle.
  2. fs module packages the arguments to the function and then calls native code.
  3. Native code gets a thread from the thread pool and initiates the OS call to write data to that file
  4. Native code returns from the function
  5. fs module returns from the fs.write() call
  6. Javascript continues to execute (whatever statements came after the fs.write() call
  7. Some time later the native code fs.write() call on a thread finishes. It obtains a mutex protecting the event loop and inserts an event in the event queue.
  8. When the Javascript engine is done executing whatever stream of Javascript it was running, it checks the event queue to see if there are any other events to run.
  9. When it finds an event in the event queue, it removes it from the event queue and executes the callback associated with that event, starting a new stream of running Javascript.

Because a new event is never acted upon until the current stream of Javascript is done executing, this is where Javascript gets is event-driven, single threaded nature even though native code threads may be used to implement some library functions. Those threads are used to make a blocking operation into a non-blocking operation, but do not affect the single threaded-ness of Javascript execution itself.

The key here is that node.js is event driven. Every new operation that triggers some Javascript to run is serialized through the event queue and the next event is not serviced until the current stream of Javascript has finished executing.


In the node.js architecture the only way to get two pieces of Javascript to run independently and at the same time is to use a separate node.js process for each. Then, they will run as two completely separate operations and the OS will manage them separately. If your computer has at least two cores, then they can literally run at the same time, each on their own core. If your computer has only one core, they will essentially be in their own process thread and the OS will time slice them (sharing the one CPU between them).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
8

I will tell it in a clear and simple way and clear the confusion :

Node Event Loop is SINGLE-THREADED But THE Other processes are not.

The confusion came from c++, which Node uses underline ( NodeJs is about 30% js + 70% c++ ).So, By default, The JS part of NodeJs is single-threaded BUT it uses a thread pool of c++. So, We have a single thread JS which is the event loop of NodeJs + 4 threads of c++ if needed for asynchronous I/O operations.

It is also important to know that The event loop is like a traffic organizer, Every request go through the loop ( which is single-thread ) then the loop organizes them to the pool threads if I/O processes are needed, so if you have a high computational app that does like heavy lifting image-processing, video-editing, audio-processing or 3d-graphics ..etc, which is not needed for most apps,So NodeJs will be a bottleneck for that high load computational app and the traffic organizer will be unhappy. While NodeJS shine for I/O bound apps ( most apps ) Like apps dealing with databases and filesystem.

Again: By default, NodeJs uses a 4 thread pool (PLUS one thread for the event loop itself ). so by default (total of 5) because of the underlying c++ system.

As a general idea, The CPU could contain one or more cores, it depends on your server(money).

Each core could have threads. Watch your activity Monitor discover how many threads you are using.

Each process has multiple threads.

The multi-threading of Node is due to that node depends on V8 and libuv ( C Library ).

So Long story short:-

Node is single-threaded for the event loop itself but there are many operations that are done outside the event Loop, Like crypto and file system (fs ). if you have two calls for crypto then each of them will reach each THREAD ( imagine 3 calls to crypto and 1 for fs, These calls will be distributed one for each thread from the 4 thread pool )

Finally: It is very easy to increase the default number of threads of the C-Library libuv thread pool which is 4 by default by changing the value of process.env.uv_threadpool_size. and also you could use clustering ( PM2 recommended ) to like clone the event-loop, like have multiple event-loops in case the single-threaded one is not enough for your high load app.

So nobody illustrates that thread pool is a c++ thing that’s nodeJs control mostly not the developer, which still asking How it’s single-thread while having a thread-pool !!

Hope that simplifies that advanced topic.

mercury
  • 2,390
  • 3
  • 30
  • 39
2

By default, the execution of your JavaScript code runs on a single thread.

However, node.js tries to make most long-running calls async. For some that just involves doing async OS calls, but for some others node.js will execute the call itself on a secondary thread, while continuing to run other JS code. Once the async call terminated, the Js callback or Promise handler will run.

jcaron
  • 17,302
  • 6
  • 32
  • 46
1

For async processing, Node.js was created explicitly as an experiment. It is believed that more performance and scalability can be achieved by doing async processing on a single thread under typical web loads than the typical thread based implementation.

  • 1
    Hi Yash, please improve you answer with all the information and share the source, thanks. https://stackoverflow.com/questions/17959663/why-is-node-js-single-threaded – Ivan Lynch May 05 '21 at 11:29