Understanding Linux I/O Models: Blocking, Non‑Blocking, Multiplexing, Signal‑Driven, and Asynchronous
This article explains the five Linux I/O models—blocking, non‑blocking, I/O multiplexing, signal‑driven, and asynchronous—detailing their system calls, synchronization characteristics, and how they map to Java BIO, NIO, and AIO implementations, with illustrative analogies and usage scenarios.
1. Basic Concepts
The five I/O models are: blocking I/O, non‑blocking I/O, I/O multiplexing, signal‑driven I/O, and asynchronous I/O.
First, we need to understand a few system‑call functions and basic concepts.
1.1 Simple Introduction to Some System‑Call Functions
recvfrom
Linux provides this interface for receiving network I/O. It receives a message from a socket and works for both connection‑oriented and connection‑less sockets.
If the return value is <0 and errno is EWOULDBLOCK or EAGAIN (the socket is marked non‑blocking and the receive operation would block or time out), the call indicates normal connection but a blocked receive.
select
The select system call allows a program to wait for input or output readiness on multiple file descriptors. On a 64‑bit machine the default limit is 2048 descriptors. When data is ready, the call does not tell which descriptor is ready, so the program must iterate, giving O(n) complexity.
poll
poll stores file descriptors in a linked list without a length limit. Its essence and complexity are also O(n).
epoll
Event‑driven; when a stream is ready, the kernel notifies the specific descriptor, eliminating the need to iterate, achieving O(1) complexity.
sigaction
Used to set the handling of signals; Linux uses the SIGIO signal to implement asynchronous I/O notification.
1.2 Synchronous & Asynchronous
Synchronous means the user process triggers an I/O operation and waits (or polls) for readiness; asynchronous means the process triggers the operation and continues doing other work, receiving a notification when the I/O completes.
1.3 Blocking & Non‑Blocking
Blocking I/O blocks the calling thread until the operation completes; non‑blocking I/O returns immediately with a status value, allowing the program to continue.
--- (the original author inserts a personal KFC anecdote here, which is omitted for brevity) ---
2. Blocking I/O Model
After learning OS concepts, we know that for both network and disk I/O, a read operation waits until data arrives, is copied to kernel buffers, and then copied to user‑space buffers.
The author likens this to waiting for a KFC bucket to be prepared: the process issues a system call, the kernel prepares data, copies it to user space, and the process remains blocked until the copy finishes.
3. Non‑Blocking I/O Model
The process periodically polls (e.g., every 5 minutes) to check if data is ready. If not ready, the kernel returns immediately, and the process can do other work.
The two phases are:
Waiting for Data Phase : non‑blocking; the process repeatedly polls the kernel.
Data Copy Phase : blocking; when data becomes ready, the kernel copies it to user space.
4. I/O Multiplexing Model
Analogous to a ticket system at a fast‑food restaurant: the OS creates a thread to accept client connections, and the program registers the events it wants to listen to.
Multiplexing is mainly used for network I/O with many clients. The execution flow involves select / poll / epoll calls that wait for any registered descriptor to become ready.
For the client, the operation appears non‑blocking; for the OS thread executing select , it blocks until a descriptor is ready.
5. Signal‑Driven I/O Model
When data is prepared, the kernel sends a signal to the application; the process catches the signal and invokes a handler to retrieve the data.
The model also has two phases:
Data Preparation Phase : non‑blocking; the kernel notifies the process when data is ready.
Data Copy Phase : blocking; the process copies the data.
6. Asynchronous I/O Model
The process issues a system call and can immediately continue other work. When the I/O operation finishes, the kernel notifies the process, which then retrieves the data.
Both stages (preparation and copy) are performed by the kernel without blocking the user process.
7. Java BIO, NIO, AIO
Operating‑system I/O models are the foundation; Java wraps these system calls to provide easier APIs.
7.1 BIO – Synchronous Blocking
Before JDK 1.4, the typical approach was to use a ServerSocket that spawns a thread per connection. If no thread is available, the client blocks or is rejected. Thread‑pool techniques can improve this model.
7.2 NIO – Synchronous Non‑Blocking
7.2.1 NIO Overview
NIO is event‑driven: when a socket becomes readable or writable, the OS notifies the application, which then reads/writes via buffers. One thread handles many connections, launching a worker only when there is data.
7.2.2 Important NIO Components
Buffer, Channel, and Selector.
7.2.2.1 Buffer
All data in NIO is handled through buffers (arrays) that maintain read/write positions.
Typical write sequence:
clear()
put() – write data into the buffer
flip() – reset cursor
SocketChannel.write(buffer) – send to network
clear()
Typical read sequence:
clear()
SocketChannel.read(buffer) – read from network
buffer.flip()
buffer.get() – retrieve data
buffer.clear()
7.2.2.2 Channel
A Channel is a bidirectional conduit for reading and writing data, similar to a pipe.
7.2.2.3 Selector
The selector registers channels and polls them; when a channel has I/O events, a thread is dispatched.
7.3 AIO – Asynchronous I/O
Applications simply call read or write ; the OS completes the operation and later notifies the application.
Efficiency order: blocking I/O < non‑blocking I/O < multiplexing I/O < signal‑driven I/O < asynchronous I/O.
Summary
From an efficiency perspective, the order is blocking I/O < non‑blocking I/O < multiplexing I/O < signal‑driven I/O < asynchronous I/O. Only the asynchronous model is truly asynchronous; the others are synchronous.
Feel free to point out any errors; the author welcomes feedback.
Additional promotional notes (e.g., MyBatis and Spring Boot advanced articles) have been omitted from this academic summary.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.