I've decided to familiarize myself with node.js and have read a several articles on the subject. What remained unclear to me is if node.js creates new threads and/or schedules tasks on threads from a thread pool when you call node.js functions.
For example if I call fs.readFile
is it executed on a different thread?
If yes, [how] can I write my own function readFileCustomized
or doLongOperation
to run on a different thread?
Node. js uses a small number of threads to handle many clients. In Node. js there are two types of threads: one Event Loop (aka the main loop, main thread, event thread, etc.), and a pool of k Workers in a Worker Pool (aka the threadpool).
This library is responsible for providing Nodejs with multithreading or the ability to provide a pool of threads in a Nodejs process for synchronous tasks to ride on. The thread pool consists of four threads, created to handle heavy-duty tasks that shouldn't be on the main thread.
Node. js runs JavaScript code in a single thread, which means that your code can only do one task at a time. However, Node. js itself is multithreaded and provides hidden threads through the libuv library, which handles I/O operations like reading files from a disk or network requests.
NodeJS server has an internal component referred to as the EventLoop which is an infinite loop that receives requests and processes them. This EventLoop is single threaded.
There is no async API for file operations so node.js uses a thread pool for that. You can see it in the code of libuv.
The pool can run 4 threads:
static uv_thread_t default_threads[4];
Blocking FS tasks are posted with uv__work_submit. For example, here's how read is implemented:
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
uv_file file,
void* buf,
size_t len,
int64_t off,
uv_fs_cb cb) {
INIT(READ);
req->file = file;
req->buf = buf;
req->len = len;
req->off = off;
POST;
}
...
#define POST \
do { \
if ((cb) != NULL) { \
uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
return 0; \
} \
else { \
uv__fs_work(&(req)->work_req); \
uv__fs_done(&(req)->work_req, 0); \
return (req)->result; \
} \
} \
while (0)
If you want to implement your own threads, you can check this great introduction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With