Fundamentals 15 min read

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.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Understanding Linux I/O Models: Blocking, Non‑Blocking, Multiplexing, Signal‑Driven, and Asynchronous

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.

Linuxasynchronous ioMultiplexingJava NIONon‑Blocking IOblocking-ioIO models
Code Ape Tech Column
Written by

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

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.