Further understanding of NIO and BIO

doubt

In the previous study, it was only mentioned that BIO is blocking IO, which blocks threads when establishing connections and reading and writing events. NIO is non-blocking IO, based on event registration, switching channels through Selector, without blocking threads. There are still some doubts about this explanation. The Selector switches the Channel without blocking the thread, but does the data exchange between the Channel and the operating system block the thread? With this kind of doubt, I further understand the knowledge of NIO, and record it below.

BIO blocking

insert image description here
After the application uses the BIO method to call the read() method, the bottom layer calls the read method of the Linux system to read data from the kernel buffer. If there is no data in the kernel buffer, the thread will be blocked until there is data, and then execute the second step , copy from the kernel buffer to the user buffer, and return the data. These two steps are completely blocked. Therefore, after using BIO, each thread will block as long as it calls the read() method. This is the blocking principle of BIO.

NIO's non-blocking

insert image description here
The Linux system provides a non-blocking read() method, which is called by NIO. When there is no data in the kernel buffer, the read() method returns Not Ready immediately, without blocking the thread. Therefore, the application needs to poll and call the read() method until data is returned. Therefore, this step is non-blocking. When the kernel buffer has data, call the read() method to copy data from the kernel buffer to the user buffer, and this step is blocked. This is the non-blocking principle of NIO.
So what are the benefits of NIO's non-blocking? The advantage is that when we call the read() method, if there is no data, then return immediately without blocking the thread, we can do other logical operations, and then call the read() method after a while to get the data , it will not be blocked in the read() method all the time, wasting this thread, and can't do anything.

NIO+IO multiplexing

In the above NIO, we use polling to call the read() method multiple times until the read data is obtained. The disadvantage of polling is that the CPU usage is too high. Because it is proposed to use the IO multiplexing provided by the Linux system to solve the problems caused by polling.

IO multiplexing is a synchronous IO model, which is a capability provided by the operating system. It uses a small number of threads to monitor multiple IO file descriptors of Linux, that is, threads are multiplexed for multiple IO requests.
If there are any IO file descriptors ready, the application will be notified to read, and
if no IO file descriptor is ready, the application thread will be blocked.
In Linux, the implementation of IO multiplexing is select/poll/epoll

insert image description here
The IO multiplexing provided by Linux can handle multiple IO requests with the fewest threads. Therefore, in the first stage, use Linux's multiplexing mechanism to monitor multiple IO connections with few threads. When none of the monitored IO connections has an IO event, the monitoring thread will also be blocked. When an IO event occurs on a certain connection, the application is notified that there is data to read, and then the application will call the read() method.
After calling the read() method, it is the same as the above NIO operation, copying from the kernel buffer to the user buffer, and returning to the application, this process is blocked.

As mentioned above, when the monitored request does not have an IO event, it is also blocked. How is it different from BIO blocking?
In NIO+ multiplexing, using the multiplexing mechanism of Linux, few threads can monitor multiple IO events, and it is a dedicated thread to monitor IO events. Even if blocking occurs during the monitoring phase, very few threads are blocked, and the threads of the application program will not be blocked, which will not affect the operation of the application program. The blocking of BIO is the blocking of the application. This difference is obvious. So NIO+IO multiplexing is a solution to improve performance in network connections.

The NIO API provided by java written before is implemented using the NIO+IO multiplexing mechanism.

Linux epoll

To put it simply, the registration callback mechanism is used to replace the polling traversal, and mmap is used to reduce the copying of file descriptors in user space and kernel space, so the performance is high. The specific details will be studied separately.

Reference article: Thorough understanding of non-blocking IO (NIO)

Guess you like

Origin blog.csdn.net/qq1309664161/article/details/128654951