1. Blocking / non-blocking, synchronous / asynchronous ( network IO)
[Thinking] What are the two stages of a typical
IO ?
- Data readiness and data reading and writing
Data ready
: According to the ready status of system
IO
operations
- block
- non-blocking
Data reading and writing
: based on how the application and kernel interact
- Synchronize
- asynchronous
Chen Shuo: When dealing with
IO
, blocking and non-blocking are both synchronous
IO
. Only when special
API is used
is asynchronous
IO
.
A typical network IO interface call is divided into two stages, namely " data ready " and " data read and write " . The data ready stage is divided into blocking and non-blocking. The result is that the current thread is blocked or returns directly.
Synchronization
means that when
A
requests a network IO interface
from
B
(or when calling a business logic API interface), the reading and writing of data are completed by the requester A itself (whether blocking or non-blocking);
Asynchronous
means that when
A
requests
B
to call a network
IO
interface (or when calling a certain business logic API interface),
it passes the requested event
to
B
and the notification method when the event occurs. A
can then handle other logic. When B listens, After the event processing is completed,
A will be notified of the processing results using the notification method agreed in advance.
2. Five IO models on Unix/Linux
a. blocking blocking
The caller calls a function and waits for the function to return. During this period, he does nothing and constantly checks whether the function has returned. He must wait for the function to return before taking the next step.
b. Non -blocking ( NIO )
Non-blocking waiting, checking whether
the IO
event is ready every once in a while. Don't be ready to do other things. Non-blocking
I/O
execution system calls always return immediately, regardless of whether the event has occurred. If the event has not occurred, -1 is returned
. At this time
, the two situations can be distinguished based on
errno . For accept , recv and send , the event has not occurred. errno is usually set to EAGAIN .
c.IO multiplexing ( IO multiplexing )
Linux
uses
the select/poll/epoll
function to implement
the IO
multiplexing model. These functions will also block the process, but
the difference from blocking
IO is that these functions can block multiple IO operations at the same time. Moreover, the IO functions of multiple read operations and write operations can
be detected at the same time.
The IO operation function is not actually called until data is readable or writable .
d.Signal - driven _
Linux
uses sockets for signal-driven
IO
and installs a signal processing function. The process continues to run without blocking. When
the IO
event is ready, the process receives the SIGIO
signal and then processes
the IO
event.
The kernel is asynchronous in the first stage and synchronous in the second stage; the difference from non-blocking IO is that it provides a message notification mechanism, which does not require the user process to continuously poll and check, reducing the number of system API calls and improving efficiency.
e. Asynchronous ( asynchronous )
In Linux
, you can call
the aio_read
function to tell the kernel the descriptor buffer pointer and buffer size, file offset and notification method, and then return immediately. When the kernel copies the data to the buffer, it notifies the application.
/* Asynchronous I/O control block. */
struct aiocb
{
int aio_fildes; /* File desriptor. */
int aio_lio_opcode; /* Operation to be performed. */
int aio_reqprio; /* Request priority offset. */
volatile void *aio_buf; /* Location of buffer. */
size_t aio_nbytes; /* Length of transfer. */
struct sigevent aio_sigevent; /* Signal number and value. */
/* Internal members. */
struct aiocb *__next_prio;
int __abs_prio;
int __policy;
int __error_code;
__ssize_t __return_value;
#ifndef __USE_FILE_OFFSET64
__off_t aio_offset; /* File offset. */
char __pad[sizeof (__off64_t) - sizeof (__off_t)];
#else
__off64_t aio_offset; /* File offset. */
#endif
char __glibc_reserved[32];
};