preface

In Java, there are three IO models: BIO, NIO, and AIO. Before introducing these three IO models, it is necessary to introduce the concepts of synchronous, asynchronous, and blocking, and non-blocking, and then to analyze BIO,NIO, and AIO from the perspective of Java and Linux OS

Synchronous and asynchronous

synchronous

Synchronization is when a call is made and does not return until the caller has processed the request.

Popular examples describe synchronization as follows:

When you call the bookstore owner and ask if they have the Sunflower Book, if it’s syncing, the bookstore owner will say, “Wait a minute, LET me check,” and start checking and checking, and when you’re done checking (it could be 5 seconds, it could be a day), you’ll get the result.

asynchronous

Asynchrony means that after making a call, we immediately get the response from the called to indicate that the request has been received, but the called does not return the result. At this time, we can process other requests. The called usually relies on events, callbacks and other mechanisms to inform the caller of its return result.

Popular examples describe asynchrony as follows:

Asynchronously, the bookstore owner tells you let me check it out, calls you when it’s done, and hangs up. And when he does, he’ll call you. Here the boss calls back and forth by “calling back.

Here refer to zhihu on this problem of answer: www.zhihu.com/question/19…

To recap synchronous and asynchronous:

The biggest difference between synchronous and asynchronous is the execution mode and return time of the called party. Synchronous means that the called party finishes something and then returns, while asynchronous means that the called party returns first, then does something, and then tries to notify the caller after completion

Blocking and non-blocking

blocking

Blocking is when a request is made and the caller waits for the result of the request to come back. In other words, the current thread is suspended, unable to do other tasks until the condition is ready to continue.

non-blocking

Non-blocking is making a request, so the caller doesn’t have to wait for the result to come back and can do something else first.

Buy a book

Did you make a phone call to ask the bookstore owner “sunflower treasure dian”, this book if you are blocking call, you will always be “hung” himself, until the book have any results, if is a blocking call, you have no matter the boss told you that your side to play the first, of course you also want to occasionally check back in a few minutes the boss have to return the result.

The difference between synchronous and asynchronous and blocking and non-blocking

Blocking and synchronization are not the same thing, synchronous, asynchronous and blocking, non-blocking are different objects, blocking, non-blocking is the caller, synchronous, asynchronous is the called

BIO, NIO, AIO Overview

  • BIO(Blocking I/O) : The traditional synchronous Blocking I/O model corresponds to the java. IO package, which provides many IO functions, such as input and output streams, to operate on files. IO operations are also performed in network programming (Socket communication).

  • NIO(New I/O): NIO is a synchronous non-blocking I/O model. The NIO framework was introduced in Java 1.4, corresponding to the Java.niO package, which provides abstractions such as channels, selectors, and buffers

  • AIO: AIO is NIO 2. NIO 2, an improved version of NIO introduced in Java 7, is an asynchronous, non-blocking IO model

Five I/O models for Linux

The three IO models in Java are briefly introduced above, and the IO related APIS provided by the three models are actually realized by IO operations at the operating system level in file processing. For example, after Linux 2.6, NIO and AIO in Java are realized by epoll. Concepts such as epoll will also be discussed later.

In fact, in Linux(Unix) operating system, there are five IO models, respectively: blocking IO model, non-blocking IO model, IO multiplexing model, signal-driven IO model and asynchronous IO model, and the four are synchronous, only the last one is asynchronous. The following analysis is based on the introduction in UNIX Network Programming Volume 1: Socket Networking apis (version 3).

Block IO model-bio

An input operation usually consists of two distinct stages:

  • Wait for the data to be ready
  • Copy data from the kernel to the process

For an input operation on a socket, the first step usually involves waiting for data to arrive from the network, and when the waiting group arrives, it is copied to a buffer in the kernel, and the second step is copying data from the kernel buffer to the application process buffer.

As you can see in the figure above, the application process receives data through the system call recvFROM, and because the kernel data is not ready, the application process blocks until the kernel is ready and copies the data from the kernel to the application’s buffer or an error occurs. The most common error is when a system call is interrupted by a signal. The process is blocked the entire time it calls recvfrom until it returns.

The blocking I/O model in Linux corresponds to the BIO model in Java. The underlying implementation of BIO is performed by calling the OPERATING system API, that is, calling the operating system Socket.

Non-blocking I/O model – NIO

The application process continuously interacts with the kernel via the system call recvFROM until the kernel datagrams are ready, and if no data is found ready, an error is returned immediately and the recvFROM request is sent later, during which time the process can do other things instead of waiting. This is non-blocking.

When an application process circulates recvFROM, which is called polling, the application process continuously polls the kernel to see if an operation is ready. Java’S NIO mapping to the Linux operating system is the non-blocking I/O model shown above

I/O multiplexing model

IO multiplexing With the select/poll/epoll functions, multiple I/OS can be registered in the same SELECT. When a user process calls the select, the SELECT listens for all the registered I/OS. If the data required by all the monitored I/OS is not ready, As soon as the datagram socket of any IO becomes readable, that is, the datagram is ready, SELECT returns the condition that the socket is readable, and then calls recvFROM to copy the read datagram into the application process buffer.

It is important to note that the IO multiplexing model does not involve non-blocking. After issuing a SELECT, a process blocks until at least one of the IO operations it listens to is ready before returning.

And in Java NIO, you can do multiplexing, mainly with the Selector multiplexer, and with the select function type here, the Selector constantly polls the channels that are registered on it, and if there’s a read or write event on one of those channels, So this Channel is ready, and it gets polled by the Selector. For more information about Java NIO multiplexing, see the related article.

Application scenarios of I/O multiplexing

The application scenarios of I/O multiplexing are as follows:

  • The server needs to process multiple listening or connected sockets simultaneously
  • The server needs to handle sockets for multiple network protocols simultaneously

System call functions for I/O multiplexing

Currently support I/O multiplexing system call functions are SELECT, pSELECT, poll, epoll. Select has long been used for polling and network event notification in Linux network programming. However, due to some inherent defects of SELECT, its application is greatly limited, for example, the maximum number of handles opened by a single process of SELECT is limited. Epoll was eventually chosen over SELECT in Linux 2.6, and is used at the base of Java NIO and AIO. For more information on the introduction and use of these system calls, see UNIX Network Programming Volume 1: Socket Networking apis (version 3)

Signal-driven I/O model

The application process installs a signal handler into the kernel, and returns immediately. The process continues to work without blocking. When the datagram is ready to be read, the kernel generates a signal for the process to notify the process, and the process calls RecvFROM to read the datagram.

Signal-driven IO is not asynchronous

Signal-driven IO is asynchronous during the data preparation phase, notifying the process when there is a datagram ready in the kernel, but it is synchronous when the recvFROM operation is called for data copy, so the overall I/O process cannot be asynchronous.

Asynchronous I/O model – AIO

The application process calls aio_read, passing the descriptor, cache pointer, cache size, and file offset to the kernel, and telling the kernel how to notify the process when the entire operation is complete. The system call then returns immediately, and while waiting for the I/O to complete, our process is not blocked and can do other things. The kernel then waits for the data to be ready, copies the data to the process buffer when it is ready, and notifies it that the entire IO operation is complete.

Java’s AIO provides an asynchronous channel API, and its underlying operating system implementation is this asynchronous I/O model

Difference from signal-driven I/O

The main difference is that signal-driven I/O lets the kernel tell us when to start an I/O operation, whereas asynchronous I/O lets the kernel tell us when the I/O operation is complete.

Comparison of five I/O models

As can be seen from the figure above, IO operations are divided into two phases:

  • Waiting for the datagram preparation phase
  • Data copy phase

The first four IO models are synchronous IO models, why say synchronous, because they are blocked in the second step of the data copy stage, which will cause the whole request process blocked, so it is synchronous, while the asynchronous IO model will not cause the request process blocked.

summary

The BIO,NIO,AIO, and Linux IO models are briefly described above. For a more detailed description of IO models, refer to UNIX Network Programming Volume 1: Socket Networking apis (3rd edition).

References & acknowledgements

  • UNIX Network Programming Volume 1: Socket Networking apis (3rd edition)
  • IO Multiplexing ramble (with epoll example)
  • How to understand the difference between blocking non-blocking and synchronous asynchronous? – zhihu
  • How to explain to your girlfriend what the five IO models of Linux are?
  • How to explain blocking, non-blocking, synchronous and asynchronous in IO to my girlfriend?