"Turn" on the node. JS single-threaded model

Source: Internet
Author: User

node. JS uses event-driven and asynchronous I/O to implement a single-threaded, high-concurrency Runtime environment, and single-threaded means only one thing at a time, so how does node. js use a single thread for high concurrency and asynchronous I/O? This article will explore the single-threaded model of node. JS with this problem:

1, High concurrency

In general, a highly concurrent solution is a multithreaded model, where the server allocates a thread for each client request, uses synchronous I/O, and the system makes up for the time overhead of synchronous I/O calls through thread switching, such as Apache, which is typically time-consuming for I/O, Therefore, this strategy is very difficult to achieve high performance, but very simple, can implement complex interactive logic.

In fact, most Web sites do not do much computing on the server side, they just receive requests to other services (such as reading data from a database), and then wait for the results to return to the client. Therefore, node. JS uses a single-threaded model for this fact, which does not allocate one thread per access request, but instead handles all requests with one main thread and then asynchronously processes the I/O operations, bypassing the overhead and complexity required to create, destroy, and switch between threads.

2. Event loop

node. JS maintains an event queue in the main thread, and when a request is received, the request is placed in the queue as an event and then continues to receive additional requests. When the main thread is idle (without a request for access), it starts looping the event queue and checks if there are any events to be handled in the queue, in two cases: if the non-I/O task is handled personally and returned to the upper layer by a callback function, and if it is an I/O task, from the thread pool Takes a thread to execute this event, specifies a callback function, and then resumes looping other events in the queue. When the I/O task in the thread is completed, the specified callback function is executed and the completed event is placed at the end of the event queue, waiting for the event loop, which is processed directly and returned to the upper-level call when the main thread loops back to the event. This process is called the event loop , as shown in:

3. Event-driven

The core of node. JS Implementation Async is event-driven. that is, it treats each task as an event and then simulates the asynchronous effect through the event Loop , in order to understand and accept the fact in a more specific and clear way, we use code to describe the implementation process:

"1" Event queue

First of all, we need to define an event queue, since it is a queue, that is a first-in-one (FIFO) data structure, we use the JS array to describe, as follows:

/**/eventqueue:[],

To facilitate understanding, we stipulate that: the first element of the array is the tail of the queue, the last element of the array is the head of the queue, the Unshfit is to insert an element at the end, pop is to pop an element from the head, thus implementing a simple queue.

"2" receive request

Define a total portal to receive user requests, as follows:

/** * Receive user requests * Each request will go to the function * Pass parameter request and response*/processhttprequest:function(request,response) {//defining an Event object    varevent =CreateEvent ({params:request.params,//Passing Request ParametersResultNULL,//Store Request ResultsCallbackfunction(){}//specifying a callback function    }); //Add the event at the end of the queueEventqueue.unshift (event);},

The function is simply to wrap the user's request into an event, put it in a queue, and then continue to receive other requests.

"3" Event loop (Events Loop)

The Loop event queue starts when the main thread is idle, so we'll define a function for the event loop:

/** * Event loop body, main thread timing execute * Loop through event queue * Handle Event * Execute callback, return to upper layer*/EventLoop:function(){    //if the queue is not empty, continue looping     while( This. eventqueue.length > 0){                 //take an event from the head of the queue        varevent = This. Eventqueue.pop (); //if it is an IO task        if(Isiotask (event)) {//take a thread out of the thread pool            varThread =Getthreadfromthreadpool (); //handing over to thread processingThread.handleiotask (Event)}Else {            //when non-IO tasks are processed, the results are returned directly            varresult =handleevent (event); //It is eventually returned to V8 by a callback function and returned to the application by V8Event.callback.call (NULL, result); }    }},

The main thread constantly detects the event queue, and for IO tasks to the thread pool for processing, non-IO tasks are processed and returned by themselves.

"4" Thread pool

After the thread pool receives the task, it directly handles IO operations, such as reading the database:

/** * Process IO Task * After completion add event to queue tail * Release Thread*/Handleiotask:function(event) {//Current Thread    varCurthread = This; //manipulating Databases    varOptdatabase =function(params,callback) {varresult =Readdatafromdb (params); Callback.call (NULL, result)}; //Performing IO TasksOptdatabase (Event.params,function(Result) {//returns the result into the event objectEvent.result =result; //when IO is complete, it will no longer be a time consuming taskEvent.isiotask =false; //Add the event back to the end of the queue         This. Eventqueue.unshift (event); //frees the current threadreleasethread (Curthread)})}

When the IO task is completed, a callback is executed, the result of the request is stored in the event, and the event is put back into the queue, waiting for the loop, and finally releasing the thread. When the main thread loops back to the event, it is processed directly.

Summing up the above process, we found that the main thread of node. JS is a single thread, which receives the request and does not directly handle it, but instead puts it into the event queue and then receives other requests, and then handles the events through the event loop at idle time, thus achieving the asynchronous effect. Of course, the IO-class task also relies on the system-level thread pool for processing. Therefore, we can simply understand thatnode. JS is itself a multithreaded platform, and it is single-threaded to the JS-level task processing.

4. Node. js Weaknesses

At this point, we should have a simple and clear understanding of node. js, but node. JS is not everything you can do.

As mentioned above, if I/O task, nodejs the task to the line pool asynchronous processing, efficient and simple, so node. JS is suitable for processing I/o-intensive tasks, but not all tasks are I/o-intensive tasks, when encountering CPU-intensive tasks, is only CPU-based operations, For example, to the data encryption (node.bcrypt.js), data compression and decompression (Node-tar), then node. JS will personally handle, a calculation, the previous task is not completed, the following task can only wait, as shown:

In the event queue, if the previous CPU calculation task is not completed, then the subsequent tasks will be blocked, the response is slow, if the operating system itself is a single core, it would be OK, but now most of the servers are multi-CPU or multicore, node. JS has only one eventloop and only one cpu/kernel, and when node. js is consumed by CPU-intensive tasks that cause other tasks to be blocked, there is a cpu/kernel that handles idle state, resulting in wasted resources. therefore, node. JS is not suitable for CPU-intensive tasks.

5. Node. js applicable Scenario

RESTful API, which is ideal for Node, because you can build it to handle tens of thousands of of connections. It still does not require a lot of logic; it essentially simply looks up some values from a database and makes them a response. Because the response is small text, inbound requests are also small amounts of text, so traffic is not high, and a machine can even handle the API needs of the busiest companies.

Real-time programs, such as chat services, are the best examples of the advantages of node. JS: Lightweight, high-traffic, and good handling of running-intensive data on cross-platform devices (albeit with low computational power). At the same time, chatting is a very worthwhile use case because it is simple and covers most of the solutions that a typical node. js will use so far.

Reference documents:

[1] node. js Achilles ' heel CPU-intensive tasks

[2] Nodejs notes: Event-driven, thread pool, non-blocking, exception handling, etc.

[3] node. JS mechanism and Principle understanding preliminary

"Turn" on the node. JS single-threaded model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.