In high-performance IO system design, there are several noun concepts that often confuses us. The details are as follows:
1 What is synchronization?
2 What is asynchronous?
3 What is blocking?
4 What is non-blocking?
5 What is synchronous blocking?
6 What is synchronous non-blocking?
7 What is asynchronous blocking?
8 What is asynchronous non-blocking?
Let me give you an example in life:
If you want a Kung Pao Chicken Dice Rice Bowl:
Synchronous blockage: You go to a restaurant to order food, then wait there, and shout: OK?
Synchronous non-blocking: After ordering in a restaurant, I went to walk the dog. But after walking for a while, he went back to the restaurant and shouted: OK?
Asynchronous blockage: When walking the dog, I received a call from the restaurant saying that the meal was ready and asked you to get it in person.
Asynchronous non-blocking: The restaurant called and said, "We know your location, and I'll send it to you later, so I can walk the dog with peace of mind."
Before we figure out the above problems, we must first understand what synchronization, asynchronous, blocking, and non-blocking are. Only when these single concepts are understood clearly, and then when combined, it will be relatively easier.
1. Synchronization and asynchronousness are for the interaction between the application and the kernel.
2. Blocking and non-blocking are different methods adopted by the process when accessing data according to the ready state of the IO operation. To put it bluntly, it is an implementation method of reading or writing operation functions. Under the blocking method, the read or writing function will wait, rather than the read or writing function will immediately return a state value.
From the above description, we can basically summarize a short sentence: synchronization and asynchronousness are the purpose, and blocking and non-blocking are the implementation methods.
1. Synchronization: refers to the user process triggering an IO operation and waiting or polling to check whether the IO operation is ready. I went out to buy clothes on the street and did this thing myself, and I couldn’t do anything else.
2. Asynchronous: Asynchronous means that after the user process triggers the IO operation, it starts to do its own things. When the IO operation has been completed, it will be notified of the completion of the IO (the characteristic of asynchronous is notification). Tell your friend to suit the size, size and color of the clothes, and let your friend entrust it to sell, and then you can do other things. (When using asynchronous IO, Java delegates IO reading and writing to the OS, and needs to pass the data buffer address and size to the OS)
3. Blocking: The so-called blocking method means that when trying to read and write the file descriptor, if there is nothing to read or it is temporarily unwritable, the program will enter a waiting state until something to read or writeable, and go to the bus stop to recharge. At this time, the recharger is not there (maybe he went to the toilet), and then we wait here until the recharger comes back. (Of course, this is not the case in real society, but it is indeed the case in computers.)
4. Non-blocking: In the non-blocking state, if there is nothing to read or cannot be written, the read and write function will return immediately without waiting. When the bank withdraws money to handle business, we will receive a small receipt. After we receive it, we can play with our mobile phones or chat with others. When we turn, the bank's speaker will notify us, and we can go.
An IO operation is actually divided into two steps: initiating an IO request and 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 block the request process, then it is synchronous IO.
The difference between blocking IO and non-blocking IO is in the first step, whether the IO request will be blocked. If it is blocked until it is completed, it is the traditional blocking IO. If it is not blocked, it is the non-blocking IO.
Synchronization and asynchronous are aimed at the interaction between the application and the kernel. Synchronization refers to the user process triggering IO operations and waiting or polling to see if the IO operation is ready. Asynchronous means that the user process starts to do its own things after triggering the IO operation, and when the IO operation has been completed, it will be notified that the IO completion will be completed.
Blocking and non-blocking are different methods adopted by the process when accessing data according to the ready state of the IO operation. To put it bluntly, it is an implementation method of reading or writing operation functions. Under the blocking method, the read or writing function will wait, rather than the read or writing function will immediately return a state value.
Therefore, IO operations can be divided into three categories: synchronous blocking (i.e. early BIO operations), synchronous non-blocking (NIO), and asynchronous non-blocking (AIO).
Synchronous blocking (BIO):
In this way, after the user process initiates an IO operation, it must wait for the IO operation to complete. Only after the IO operation is truly completed can the user process run. JAVA's traditional IO model belongs to this method.
Synchronous non-blocking (NIO):
In this way, the user process can return to do other things after launching an IO operation, but the user process needs to ask whether the IO operation is ready from time to time, which requires the user process to constantly ask, thereby introducing unnecessary waste of CPU resources. Among them, currently JAVA's NIO is synchronous non-blocking IO.
Asynchronous non-blocking (AIO):
In this way, after the application initiates an IO operation, it does not wait for the kernel's IO operation to complete, and will notify the application after the kernel completes the IO operation.
Synchronous blocking IO (JAVA BIO):
Synchronize and block, the server implementation mode is to connect to one thread, that is, when the client has a connection request, the server needs to start a thread for processing. If this connection does not do anything, it will cause unnecessary thread overhead, and of course it can be improved through the thread pool mechanism.
Synchronous non-blocking IO (Java NIO):
Synchronous non-blocking, the server implementation mode is to request one thread, that is, the connection requests sent by the client will be registered with the multiplexer. The multiplexer polls the connection to the I/O request and starts 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 constantly ask.
Asynchronous blocking IO (Java NIO):
In this way, after the application initiates an IO operation, it does not wait for the kernel's IO operation to complete, and will notify the application after the kernel completes the IO operation. This is actually the most critical difference between synchronization and asynchronous. Synchronization must wait or actively ask whether the IO is completed. So why is it blocked? Because it is done by select system calls at this time, and the implementation of the select function itself is blocking, and one advantage of using select function is that it can listen to multiple file handles at the same time (if from the perspective of UNP, select is a synchronous operation. Because after 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 return immediately. After the IO operation is truly completed, the application will be notified that the IO operation is completed. At this time, the user process only needs to process the data and does not need to perform 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 architectures with relatively small connections and fixed connections. This method requires high server resources and concurrency is limited to applications. It is the only choice before JDK1.4, but the program is intuitive, simple 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. Concurrency is limited to applications and has relatively complex programming. JDK1.4 has started to support it.
The AIO method is used for architectures with a large number of connections and a relatively long connection (reoperation), such as album servers, which fully call the OS to participate in concurrent operations, and the programming is relatively complicated. JDK7 has begun to support it.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.