For a long time I thought that event loop implementation (libuv?) used in Chrome and Node.js used threads. But then I was reading this article on lightweight threads in Java that stated the following:
...instead of creating threads for each concurrent task (and blocking tasks), a dedicated thread (called an event loop) looks through all the tasks that are assigned to threads in a non-reactive model, and processes each of them on the same CPU core.
And the the book Computer Systems. A Programmer’s Perspective in the chapter on concurrent applications states that modern operating systems provide three basic approaches for building concurrent programs (3 approaches to implementing logic flows):
Processes. With this approach, each logical control flow is a process that is scheduled and maintained by the kernel. Since processes have separate virtual address spaces, flows that want to communicate with each other must use some kind of explicit interprocess communication (IPC) mechanism.
I/O multiplexing. This is a form of concurrent programming where applications explicitly schedule their own logical flows in the context of a single process. Logical flows are modeled as state machines that the main program explicitly transitions from state to state as a result of data arriving on file descriptors. Since the program is a single process, all flows share the same address space.
Threads. Threads are logical flows that run in the context of a single process and are scheduled by the kernel. You can think of threads as a hybrid of the other two approaches, scheduled by the kernel like process flows and sharing the same virtual address space like I/O multiplexing flows.
So now I'm wondering now if the event loop falls under I/O multiplexing
logical flow and doesn't use threads?
Event loop is an endless loop, which waits for tasks, executes them and then sleeps until it receives more tasks. The event loop executes tasks from the event queue only when the call stack is empty i.e. there is no ongoing task. The event loop allows us to use callbacks and promises.
The event loop is what allows Node. js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible. Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background.
The Event Loop was implemented to assist with the interactions between these asynchronous components and the main application thread. The Event loop is implemented as part of the libUV library that provides cross-platform asynchronous I/O in Node. js.
JavaScript has a runtime model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks. This model is quite different from models in other languages like C and Java.
Node.js is a single-threaded event-driven platform that is capable of running non-blocking, asynchronously programming. These functionalities of Node.js make it memory efficient. The event loop allows Node.js to perform non-blocking I/O operations despite the fact that JavaScript is single-threaded.
These functionalities of Node.js make it memory efficient. The event loop allows Node.js to perform non-blocking I/O operations despite the fact that JavaScript is single-threaded. It is done by assigning operations to the operating system whenever and wherever possible.
C: event-logger is an event listener, and registers an event listener for each of the possible log message types (for example, TRACE, WARN, and so forth). D: event-logger is missing the off () method, which is an integral part of the logger interface.
In general, in most browsers there is an event loop for every browser tab, to make every process isolated and avoid a web page with infinite loops or heavy processing to block your entire browser. The environment manages multiple concurrent event loops, to handle API calls for example. Web Workers run in their own event loop as well.
I have nothing to do with V8 team, but I'll try to answer the question.
First of all, V8 itself has nothing to do with an event loop. Node.js uses libuv to implement the event loop plus abstractions for OS-specific APIs (network, FS, and so on). The event loop itself is run on a single OS thread and most of the network operations are executed on that thread based I/O multiplexing APIs (epoll, kqueue, etc.).
But libuv also has a thread pool to run blocking I/O (e.g. FS, DNS lookups) and CPU intensive operations (e.g. crypto). The thread pool is integrated (communicates) with the event loop through an in-memory queue. When a blocking/CPU intensive task has to be started it's put into the queue and later on one of the threads starts processing it.
So, Node.js uses a number of approaches to achieve concurrency among the user operations: OS threads (BTW this includes the worker_threads
module), I/O multiplexing, multiple processes (with the child_process
module).
V8 also uses a number of OS threads for its own purposes (say, GC), but it doesn't need to be aware of the event loop or provide any abstractions for the OS-level APIs. Its goal is to, well, execute the given JS code and provide a solid embedder API, so that you can build a browser/runtime with it.
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