Search code examples
node.jsmultithreadingrequestlisten

Does a NodeJS server use multithreading?


I have a question about nodeJS (specifically with regards to version 9). Using this project -- https://github.com/howardchung/jsminer, I'm running a nodeJS server, if that is the right word. I spin it up on my command lien by running

node index.js

This is the only process I run. Within the "index.js" file, express is used to create endpoints on which to listen, for instance

var express = require('express');
var app = express();
...
app.get('/work', function(req, res) {
    console.log("client requested work!");
    //send constructed block to client
    //client mines block
    //when client succeeds, client hits /submit
    res.json({
        result: curr_block
    });
});

If I were to call

http://localhost:5000/work

at the same time, does one call get blocked until the other call completes or are they handled simultaneously. In other words, is multithreading enabled?


Solution

  • Some of it's underlying C++ components do but that capability is not exposed to you so you can't write threaded code yourself. The Javascript language itself doesn't provide support for threads.

    To take advantage of multiple CPU's you can either spawn separate child processes or run a lot of parallel instances of the same process.

    In other words you cant do multithreading; but you can still do multiprocessing.

    ...does one call get blocked until the other call completes or are they handled simultaneously.

    They are accepted in parallel, assuming your requests are primarily I/O-bound (use the database, filesystem etc..) instead of CPU-bound (perform encryption, decryption, compression etc..).

    Node.js offers a type of pseudo-concurrency facilitated by using an Event Loop and the programmer writing code in an Event-driven programming style (callbacks, Promises etc...), instead of creating separate threads for each request.

    An oversimplification would be like this:

    • Request A arrives and is put on the event queue.
    • Request A requests data from the database.
    • Request B arrives and is put on the event queue.
    • Request B requests data from the database.
    • Request B's database request arrives and request B is served with data.
    • Request A's database request arrives and request A is served with data.

    As you can see, Node accepts concurrent requests and serves each when necessary. It doesn't stop accepting incoming requests until another is served. It's non-blocking.

    However the above scenario is a primarily I/O-bound example, where the Node.js concurrency model shines.

    In contrast, if your requests are primarily CPU-bound (instead of I/O bound) then you freeze the single thread (remember Node.js is single-threaded) it runs on, requests cannot be accepted and your server "freezes" for the duration of that single request CPU computation.

    ...In other words, is multithreading enabled?

    I assume that a lot of Node's underlying libraries (libuv for example) do use multiple threads, however the ability to directly control threads is not exposed to the user (although in theory you can write native C++ addons where you can harness multithreading).

    If you're worried that you're not utilising all CPU cores, you should look into the cluster module to spin up multiple Node.js server processes. In this case the problem is taken off your hands; the O/S scheduler should, in most cases, spread the processes across available cores; this however is called multi-processing, not multithreading.