There are five types of I/O models under UNIX:
1. Blocking I/O
2. Non-blocking I/O
3. I/O multiplexing (SELECT and poll)
4. Signal-driven I/O (SIGIO)
5. Asynchronous I/O (POSIX aio_ series functions)
The IO request is divided into two steps:
1. Copy the data from the storage media (disk, network, etc.) to the kernel buffer, which is called data ready and can be read by the user application.
2. Copy the data from the kernel buffer to the user buffer by the user application.
① blocking I/O model process keeps blocking until data copy is complete
We treat the function Recvfrom as a system call, no matter how it is implemented, there is usually a switch running from the application process to the kernel, and a transition back to the application process over time.
The application calls an IO function, causing the application to block and wait for the data to be ready. If the data is not ready, wait all the time. If the data is ready, copy the data from the kernel to the user space, and the IO function returns the success indication.
The process calls Recvfrom, which is called until the datagram arrives and is copied into the buffer of the application process or an error occurs, and common errors such as system calls are interrupted by the signal.
The process is blocked at the beginning of the call to Recvfrom and the entire time it returns, and after the function returns successfully, the application process begins processing the datagram.
② non-blocking I/O model data is always polled before it is ready
We set up a set of interfaces to non-blocking is to tell the kernel, when the requested I/O operation cannot be completed, do not sleep the process, but return an error. This way our I/O operations function will constantly test whether the data is ready, and if not, continue testing until the data is ready. In this continuous testing process, the CPU will be a lot of time.
The first three calls to Recvfrom still have no data to return, so the kernel immediately returns a ewouldblock error. When Recvfrom is called for the fourth time, the datagram is ready, copied to the application buffer, RECVFROM returns a success indicator, and then we process the data.
When an application process calls Recvfrom on a non-blocking descriptor loop like this, we call this process polling (polling). Since the application process continuously queries the kernel like this to see if an operation is ready, this is a huge waste of CPU time, so this model is only occasionally encountered.
The ③I/O multiplexing model adds a system call Select to help the process monitor multiple I/O
The I/O multiplexing model uses the Select or poll function, which also blocks the process, but unlike blocking I/O, these two functions can block multiple I/O operations at the same time. I/O functions can be detected at the same time for multiple read operations, multiple write operations, and I/O operation functions are not actually invoked until there is data readable or writable.
As soon as the data is ready, the Select call returns and the application calls Recvfrom to copy the data from the kernel area to the user area.
Looking closely at the example diagram, it is found that the Select model seems somewhat disadvantage, that is, two system calls were made before and after, one more time than the previous model. However, the Select model has its obvious advantage: after each select block is returned, you can obtain multiple sockets that are ready (that is, a select can manage multiple sockets, similar to monitoring multiple socket events in readiness).
Compared with the blocking IO model, the SELECTI/O multiplexing model is equivalent to early blocking. When data arrives, the call to Recv is not blocked by waiting for data to be ready.
④ Signal-driven I/O model process to confirm data readiness with received signals
We can use the signal to let the kernel notify us with signal Sigio when the data is ready, this method is called signal-driven I/O
First, we allow the socket to signal driver I/O and install a signal handler through the system call sigaction. This system call returns immediately, and the process continues to work, and it is non-blocking. When the datagram is ready to be read, a Sigio signal is generated for the process. We can then call recvfrom in the signal handler to fetch the datagram.
⑤ Asynchronous I/O process is not blocked, handing the task to kernel processing
We let the kernel initiate the operation and notify us when the entire operation is complete, including copying the data from the kernel to our own buffer zone.
Call the Aio_read function, tell the kernel description word, buffer pointer, buffer size, file offset, and how to notify, and then immediately return. Notifies the application when the kernel copies the data to the buffer.
Comparison of five I/O models
The first four models differ primarily in phase one, because the second stage of the first four models is basically the same: when the data is copied from memory to the caller's buffer, the process is blocked by the recvfrom call. However, the two phases of asynchronous I/O model processing are different from the first four models.
synchronous I/O vs. asynchronous I/ o
- Synchronous I/O: The request process is blocked until the I/O operation is completed
- asynchronous I/O: The request process is not blocked until the I/O operation is complete
Of the five I/O models above, the first four are synchronous I/O (they wait in the same way, the relocation action is the same) because the recvfrom call blocks the current request process.
Only the last IO belongs to asynchronous I/O!
The so-called synchronization, when the data is copied from the storage media to the kernel buffer (the process of preparing the data), requires the user to copy the data to the user buffer themselves.
The so-called async, Step 1, 2 users do not care, as long as the IO request, after the IO results can be obtained.
Therefore, the first 4 kinds of IO models are synchronous!!!
Blocking, non-blocking, synchronous, asynchronous generalization:
Blocking, non-blocking: whether the process/thread is ready to access the data, whether the process/thread needs to wait;
Synchronous, asynchronous: access to data, synchronization needs to actively read and write data, in the process of reading and writing data is still blocked, asynchronous only requires I/O operation to complete the notification, not actively read and write data, the operating system kernel to complete the data read and write.
Five types of I/O Models for UNIX systems