The difference between NIO, BIO, AIO

In the design of high-performance IO system, there are several terms and concepts that often confuse us. details as follows:

1. Synchronous and asynchronous are for the interaction between the application and the kernel. Synchronous/asynchronous are two processing strategies that emphasize the outcome/opportunity cost of dealing with things in time; stressing the outcome means impatiently waiting for the outcome, but whether the outcome is right or wrong, you have to give me a result immediately anyway Response; emphasizing the time opportunity cost means that it is extremely difficult to accept the wasted time waiting for the result, but is not so eager for the result, regardless of the result for the time being (let the processor take the initiative to notify the result after processing / take the initiative to obtain the result when it is free) and turn to to deal with other things

2. Blocking and non-blocking refer to the different ways that the process takes according to the ready state of the IO operation when it accesses data. To put it bluntly, it is an implementation of a read or write operation function. In blocking mode, read or write The write function will always wait, and in non-blocking mode, the read or write function will immediately return a status value. 3. Synchronous/asynchronous is macroscopic (inter-process communication, usually manifested in the processing of network IO), blocking/non-blocking is microscopic (in-process data transmission, usually manifested in the processing of local IO); blocking and non-blocking Blocking is the manifestation of synchronous/asynchronous The above description can basically be summed up in a short sentence, synchronous and asynchronous are the purpose, and blocking and non-blocking are the way to achieve.

serial number noun explain Example
1 Synchronize Refers to the user process triggering an IO operation and waiting or polling to see if the IO operation is ready Go to the street to buy clothes, do it yourself, and you can't do anything else.
2 asynchronous Asynchronous means that the user process starts to do its own thing after triggering the IO operation, and when the IO operation has been completed, it will be notified of the completion of the IO (the feature of asynchronous is the notification) Tell your friends the size, size, and color of your clothes, and ask your friends to sell them, and then you can do other things yourself. (When using asynchronous IO, Java delegates IO reading and writing to the OS for processing, and the data buffer address and size need to be passed to the OS)
3 block The so-called blocking mode means that when trying to read or write the file descriptor, if there is nothing to read at that time, or it is temporarily unwritable, the program enters a waiting state until something is readable or writable. We went to the bus station to recharge and found that at this time, the recharger was not there (probably went to the toilet), and then we waited here until the recharger came back. (Of course, in the real world, this is not the case, but it is true in computers.)
4 non-blocking In the non-blocking state, if there is nothing to read or write, the read and write functions return immediately without waiting. When withdrawing money in the bank to do business, we need to get a small ticket. After receiving it, we can play with our mobile phones or chat with others. When it is our turn, the bank's speaker will notify us, and we can go.

 Next, let's understand the IO type of the combination method, which is easier to understand. 

Synchronous blocking IO (JAVA BIO) : Synchronous and blocking, the server implementation mode is one connection and one thread, that is, when the client has a connection request, the server needs to start a thread for processing. If the connection does not do anything, it will cause unnecessary Thread overhead, of course, can be improved by the thread pool mechanism.  

Synchronous non-blocking IO (Java NIO) : Synchronous non-blocking, the server implementation mode is one request and one thread, that is, the connection request sent by the client will be registered on the multiplexer, and the multiplexer polls to connect with I /O request to start a thread for processing. The user process also needs to ask whether the IO operation is ready from time to time, which requires the user process to keep asking.  

Asynchronous blocking IO (Java NIO) : This method means that after the application initiates an IO operation, it does not wait for the completion of the kernel IO operation, and will notify the application after the kernel completes the IO operation. This is actually the most critical difference between synchronization and asynchrony , synchronization must wait or actively ask whether IO is completed, so why is it blocking? Because it is done through the select system call at this time, and the implementation of the select function itself is blocking, and the use of the select function has the advantage that it can monitor multiple file handles at the same time (if from the perspective of UNP, select is synchronous operation. Because after the select, the process also needs to read and write data), thereby improving the concurrency of the system!  

Java AIO (NIO.2)) asynchronous non-blocking IO : In this mode, the user process only needs to initiate an IO operation and then return immediately. After the IO operation is truly completed, the application will be notified of the completion of the IO operation. At this time, the user process only needs to process the data, and does not need to perform the actual IO read and write operations, because the real IO read or write operations have been completed by the kernel.

Analysis of applicable scenarios for BIO, NIO, and AIO:

The BIO method is suitable for a structure with a relatively small number of connections and a fixed number of connections. This method has relatively high requirements on server resources, and concurrency is limited to applications. It is the only choice before JDK1.4, but the program is intuitive and easy to understand.

The NIO method is suitable for architectures with a large number of connections and relatively short connections (light operation), such as chat servers, where concurrency is limited to applications, and programming is more complicated. JDK1.4 began to support it.

The AIO method is used for architectures with a large number of connections and relatively long connections (heavy operations), such as photo album servers. It fully calls the OS to participate in concurrent operations, and the programming is more complicated. JDK7 began to support it.

After figuring out the above concepts, let's go back and look at the Reactor mode and the Proactor mode.  

(In fact, both blocking and non-blocking can be understood as concepts only under the category of synchronization. For asynchronous, there will be no blocking and non-blocking. For user processes, after receiving asynchronous notifications, they directly operate the process in the user space. Data is good.)

Let's first look at the Reactor pattern, which is used in synchronous I/O scenarios. Let's take a read operation and a write operation as an example to see the specific steps in Reactor:

Read operation:

 1. The application registers the read-ready event and the associated event handler 

 2. The event separator waits for the occurrence of the event  

 3. When a read ready event occurs, the event separator calls the event handler registered in the first step  

 4. The event handler first performs the actual read operation, and then performs further processing according to the read content. The write operation is similar to the read operation, except that the first step is to register the write-ready event.

Let's take a look at the process of read and write operations in Proactor mode:

Read operation:

1. The application initializes an asynchronous read operation, and then registers the corresponding event handler. At this time, the event handler does not focus on the read ready event, but on the read completion event, which is the key to distinguishing it from Reactor.

2. The event separator waits for the read operation complete event    

3. When the event separator waits for the read operation to complete, the operating system calls the kernel thread to complete the read operation (asynchronous IO is the operating system responsible for reading and writing data to the buffer passed in by the application for application operation, and the operating system plays the role of important roles), and put the read content into the buffer passed by the user. This is also different from Reactor. In Proactor, the application needs to pass the buffer.    

4. After the event separator captures the read completion event, it activates the event handler registered by the application, and the event handler reads data directly from the buffer area without the need for an actual read operation.    

Write operations and read operations in Proactor, but the event of interest is the write completion event.

As can be seen from the above, the main difference between Reactor and Proactor modes is who performs the real read and write operations. In Reactor, the application needs to read or write data by itself, while in Proactor mode, the application does not The actual read and write process needs to be performed, it only needs to read or write from the buffer area, and the operating system will read the buffer area or write the buffer area to the real IO device.

To sum up, synchronization and asynchrony are relative to the interaction between the application and the kernel. Synchronization needs to actively ask, and when asynchronous, the kernel notifies the application when an IO event occurs, while blocking and non-blocking are only the system. It's just how the function is implemented when calling the system call.

If you want to eat a Kung Pao Chicken Rice Bowl: 

Sync Blocking: You go to the restaurant to order, and then wait there, shouting: Okay! 

Synchronous non-blocking: After ordering at the restaurant, go for a walk with the dog. But after slipping for a while, I went back to the restaurant and shouted: Okay! 

Asynchronous blocking: When walking the dog, you receive a call from the restaurant saying that the meal is ready, and asks you to pick it up in person. 

Asynchronous non-blocking: The restaurant called and said, we know your location, we will deliver it to you as soon as possible, and you can walk the dog with peace of mind.

"An IO operation is actually divided into two steps: initiating an IO request and an actual IO operation. 
The difference between synchronous IO and asynchronous IO is whether the second step is blocked. If the actual IO read and write blocks the request process, then it is synchronous IO. .The 
difference between blocking IO and non-blocking IO is the first step, whether the IO request will be blocked. If it blocks until it is completed, it is traditional blocking IO. If it does not block, then it is non-blocking IO. 

Synchronization and asynchronous are for applications. In terms of interaction with the kernel, synchronous means that the user process triggers IO operations and waits or polls to see if the IO operations are ready, while asynchronous means that the user process starts to do its own things after triggering the IO operation, and when the IO When the operation has been completed, you will be notified of the completion of IO. Blocking and non-blocking are different methods for the process to access data according to the ready state of the IO operation. To put it bluntly, it is a read or write operation. The way the function is implemented, in blocking mode, the read or write function will always wait, while in non-blocking mode, the read or write function will immediately return a status value. 
Therefore, IO operations can be divided into three categories: synchronous blocking ( That is, early IO operation), synchronous non-blocking (NIO), asynchronous (AIO). 
Synchronous blocking: 
In this way, after the user process initiates an IO operation, it must wait for the completion of the IO operation, and only when the IO is really completed After the operation, the user process can run. The traditional IO model of JAVA belongs to this method. 

Synchronous non-blocking: 
In this method, the user process can return to do other things after initiating an IO operation, but the user process needs to ask IO from time to time. Whether the operation is ready, this requires the user process to keep asking, thereby introducing unnecessary waste of CPU resources. Among them, JAVA's NIO currently belongs to synchronous non-blocking IO. 
Asynchronous:  In
this way, after the application initiates an IO operation , do not wait for the completion of the kernel IO operation, and will notify the application after the kernel completes the IO operation." 

This sentence is relatively clear 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325680535&siteId=291194637