preface

Coding should be a lifelong career, not just 30 youth rice This article has included making https://github.com/ponkans/F2E, welcome to Star, continuously updated

The interviewer asks: What is congestion?

If you have to think twice about this question, you’re talking to me about Node async non-blocking. Please have a good look at the following article.


I hope you learned something from each article. This article is about the principle of Node asynchronous non-blocking. I hope you learned something from each article:

  • Blocking and non-blocking nature and difference
  • Nature and difference between synchronous and asynchronous
  • Node asynchronous non-blocking nature

PS: The bottom foundation determines the superstructure. Please pay attention to the foundation


Asynchronous nonblocking

Asynchronous non-blocking is a common topic when referring to Node, along with events, callbacks, messages, and so on.

Looking at these concepts is like chasing a bad girl. You think you know her, but sometimes you don’t.

This article will take you layer upon layer, from the bottom up in-depth understanding of these concepts, so that you see the true face of this slag woman.

Blocking non-blocking

Many people confuse non-blocking with asynchronous, and the two concepts do have similarities, but they must be fundamentally different or they wouldn’t be split into two terms.

The first thing we have to think about is what does blocking mean? The answer, of course, is progress. The five states of a process are created, ready, running, blocked, and terminated. So when we talk about blocking and not blocking, we must mean the process.

With this in mind, when a process makes a call, if it goes from running to blocking, it is a blocking call, and if it goes from non-blocking.

Synchronous and asynchronous

So let’s just be clear about what synchronous asynchronous means, right? We often say that a so-and-so method is an asynchronous method, or that a so-and-so call is an asynchronous call. Visible synchronous asynchrony describes the nature of a call.

What is synchronization? When a function call is made, it does not return until the result is received. By this definition, most functions are called synchronously.

Asynchrony is the opposite of synchronization. When an asynchronous function call is made, the caller does not get the result immediately. When the asynchronous function is complete, the caller is notified by status, notification, or callback.

There are two important points here:

  • The first is that you can return the result before you get it, without calling a blocking thread wait.
  • The second is being able to actively notify the main thread and perform a callback before it finishes.

For the above explanation, some partners may still be a little confused, it is difficult to understand the relationship between the two. Don’t worry, look down.

Ring the kettle

As for the above concept, there is a very classic loud kettle explanation on the Internet. Here, Strange extends to everyone and talks about his own understanding.


Grandpa Wang next door has a kettle. Grandpa Wang often uses it to boil water.

Uncle Wang put the kettle on the fire, and then did nothing until the water boiled and uncle Wang did something else. (Synchronous blocking)

Uncle Wang felt a little silly and didn’t want to wait. After I put the kettle on, I just went to watch TV to make sure it was on (synchronous non-blocking).

Uncle Wang bought a loud kettle. He put the kettle on the fire and waited for the water to boil. When the water boiled, the kettle would make a sound (asynchronous blocking).

Uncle Wang felt foolish again. He put the kettle on the fire and then went to watch TV. He didn’t have to take a look at the kettle because it would make a sound to inform him when the water was boiling. (Asynchronous non-blocking)

In the above four chestnuts, blocking non-blocking indicates the state of the big ye, while synchronous non-synchronous indicates the call posture of the kettle. The kettle can automatically ring when it is ready, which is equivalent to our asynchronous definition, notifies the main thread and calls back when it is finished. So asynchrony generally works in conjunction with non-blocking.

Blocking AND non-blocking I/OS

With the above wang uncle inspired, we may have some basic concepts of cognition, then let’s further discuss non-blocking IO and asynchronous IO.

Blocking IO

Blocking IO as its name indicates, the main thread will block when calling the IO method and continue running until the IO result is returned. This means that the call will not return until the operation is complete.

The first thing you need to know is the cost of reading a disk. Reading a disk involves disk hunting, reading data in the corresponding sector, and then storing the data in memory. So blocking IO must be replaced, as you can see in the figure below.

Blocking IO
Non-blocking IO

Non-blocking I/O is the opposite of blocking. After the OPERATING system initiates an I/O call, it can return directly without data, so that the main thread will not be blocked, and then the operating system can handle the operation of reading disks without the main process being blocked. This is called non-blocking I/O.


By the way, most IO devices now support DMA(Direct Memory Access). The meaning of DMA is to relieve the pressure of the PROCESSOR during I/O. The CPU only needs to initialize the DMA controller and issue operation commands to the I/O interface. The I/O interface makes DMA requests and then transfers data directly between the memory and the peripheral devices without the central processing unit (CPU), during which time the CPU can perform other tasks.


Going back to our non-blocking IO, it’s pretty obvious that the process doesn’t have to wait for the function to return and can do something else.

There is an obvious drawback, however, that the time we want to read is not in place when the function returns. Personally, if your next operation immediately relies heavily on IO data, it makes no difference whether you block or not.

If your next operation is not strongly dependent, you can first execute the non-strongly dependent program, and then to see if the IO is good, so that the CPU waiting for the IO period can be used. The following figure shows the process of non-blocking I/O.

PS: Blocking and non-blocking is the same as before, looking at whether the calling process is blocking or not.

Non-blocking IO

Evolution of polling technology

One of the key points I made above is that when we’re not blocking IO, the time we want to read it is not in place when the function returns.

Just like the old man who is boiling water, when he does not ring the kettle, although he is watching TV while boiling water, he also wants to check whether the water is on or not.

I have the same thing here, we don’t know when the data is going to be good, so we have to actively probe if the IO data is in place, because we’re actively probing, and to be sure, polling is not asynchronous, it’s not a kettle.


Here I need to sort out a detail for you. You may often hear a lot of IO related nouns, such as recv, select, epoll, kqueue, etc., but you may not have a very intuitive cognition of them. We’re going to read a file in two steps.

The first is to read the file, and the second is to get the result of the read.

Recv can block or not according to the parameters. The non-blocking IO we are talking about is only in the read step, while select and epoll are the things that the second step (get the results) does. They are blocking methods. One should not confuse the two steps.

So let’s go over our polling technique.

Original: read

Read is the primitive polling method. Read itself is a method that reads files. In a C++ call, if the NONBLCOK property is set, it will immediately return -1.

C: C: C: C: C: C: C First block read.

Blocking IO

So what do we do later when we need this IO result? We can only call the read method until it does not return -1, and then take the file data from a char[], as shown below.

Non-blocking IO

Process is roughly the diagram below, although at the time of launch IO non blocked, but its drawback is obvious, he needs to constantly when get to polling, here will be consuming CPU, if this is a multicore machines may be good, if it is a single-core, that a CPU by these meaningless polling consumption here, very silly (fear of not a han han) of iron.

Non-blocking IO
Advanced: select

We talked about read earlier, and the downside of reading is that it requires constant polling. Otherwise, we can only listen to one file, so if I need to read two files, that means I’m going to call the read method twice, and then I’m going to have to poll one, and then poll the other one when it returns.

You might say, well, I can just write two code calls to read in one while(True).

What if we have to read 10 files? 100 files? Are you going to write 100? The answer is definitely NO. In view of the continuous empty round question, and multi-file listening problem, the operating system gives a better solution, select call.

After the read operation, we can get a fd (file descriptor). If you don’t understand the file descriptor, you can check out the “Large Front-end Advanced Node.js” series of multi-process model implementations, which are described in detail.

If we make 100 read calls, that’s 100 FDS. Select can listen for file descriptors in batches. When we call select, the current process is blocked. Select is blocking call).

When an IO operation belonging to one of the file descriptors in the listening batch ends, the operating system initiates an interrupt. The interrupter simply wakes up the blocked process.

This means that the data for a file descriptor is ready, but the question is which one? The hen. Do how? Polling. Scan all listening FDS, retrieve ready file descriptors, and read the response data.

In this way, the CPU consumption problem of polling is solved by blocking the process, interrupting the wake up problem, and the multi-file listening problem is solved by the multi-handle listening feature of SELECT.

The general process is shown below.

Evolution: epoll

Select solves most of the problems, but introduces a new problem, as described above, the process is confused when woken up, who woke me up? He wants to see them one by one.

This traversal can have a significant impact on performance if there are too many files, so SELECT is designed to listen for an upper limit of 1024 file descriptors.

To solve the holes left by SELECT, the most extensive epoll we use today was born.

The key optimization of ePoll is the introduction of something between a process and a FD: EventPoll.

When an I/O ends, the interrupt program does not wake up the process directly. Instead, it puts the IO-ready file descriptor in EventPoll first. Later, when the process is woken up, it does not need to poll the entire FD list and only needs to fetch the ready file descriptor in EventPoll.

This is the evolution of the current mainstream polling technology

Node asynchronous non-blocking IO (part 2)

As mentioned earlier, read provides a non-blocking way to call I/O, but the system needs to actively fetch data when it needs it, rather than being notified asynchronously. Epoll, however nice, is not a ringing kettle.

Is there a kettle that doesn’t ring? Not really. Linux offers AIO mode, a native asynchronous interface based on signals and callbacks, but unfortunately this is only available in Linux and has some drawbacks.

Asynchronous non-blocking is a Node feature, as stated at the beginning of this article. No, all of the ideas we discussed above are based on a single process. If you take advantage of multiple processes, Node can make one itself, although the operating system level does not support the kettle.

Eventloop + thread pool

As I subtitled above, the principle behind asynchronous non-blocking IO is EventLoop + thread pool. Node has different system calls on different platforms, but the basic architecture is pretty much the same.

Specific Node asynchronous non-blocking IO architecture, please look forward to the weird Large Front-end Advanced Node.js series asynchronous non-blocking (part 2).

conclusion

This article has included making https://github.com/ponkans/F2E, welcome to Star, continuously updated

This article is the basis, it is necessary to master, behind the understanding will have the feeling of a duck in water ~

In this article, Geeky mainly helps us clear up a lot of confusing concepts, and introduces our current IO situation from the perspective of the operating system. To sum up:

  • Blocking Non-blocking looks at the process status.
  • Asynchronous non-asynchronous look at the nature of the call.
  • Read is synchronous non-blocking and can be regarded as non-blocking IO, but the method of obtaining the result data is a synchronous blocking method, commonly used is the above mentioned epoll.

PS: I have read some articles on the Internet, but they are not mentioned in the point. To understand this thing, you need to understand it from the very beginning and the essence, so that you can truly understand the structure!

How does Node asynchronously non-block? What exactly is eventLoop? Save that for this series.

Recent original portal, Biubiubiu:

  • Collection of dACHang front-end component library tools (PC, mobile, JS, CSS, etc.)
  • Large Front-end Advanced Node.js series P6 Essential Scaffolding /CI building ability (PART 1)
  • “Big front-end basic Components” series of 80 lines to achieve a web watermarking NPM package
  • “Big Front-end Advanced Security” series HTTPS details

Like the small partner to add a concern, a praise oh, Thanksgiving 💕😊

Contact me/public number

Wechat search “water monster” or scan the qr code below reply “add group”, I will pull you into the technical communication group. Honestly, in this group, even if you don’t talk, just reading the chat is a kind of growth. (Ali technical experts, aobing authors, Java3y, mogujie senior front end, Ant Financial security experts, all the big names).

The water monster will also be regular original, regular with small partners to exchange experience or help read the resume. Add attention, don’t get lost, have a chance to run together 🏃 ↓↓↓