Understanding Blocking, Non‑Blocking, and I/O Multiplexing Models in Unix Network Programming
This article introduces the basic concepts of I/O and explains three Unix network programming models—blocking I/O, non‑blocking I/O, and I/O multiplexing—detailing their workflows, advantages, disadvantages, and practical analogies for better comprehension.
Preface
The book Unix Network Programming describes five I/O models: blocking I/O, non‑blocking I/O, I/O multiplexing, signal‑driven I/O, and asynchronous I/O. This article focuses on the basic I/O concepts and the three models of blocking I/O, non‑blocking I/O, and I/O multiplexing for learning purposes.
1. What Is I/O
Computer‑centric view of I/O: Any data transfer between the CPU/memory and external devices (e.g., printers, mouse, keyboard) is considered I/O. It includes both the devices themselves and the read/write operations on them.
Program‑centric view of I/O:
Modern operating systems separate memory into user space and kernel space.
User space: Application code runs here with limited privileges and cannot directly access kernel space or hardware.
Kernel space: The core of the OS that manages processes, memory, device drivers, files, and networking, determining system performance and stability.
The OS prevents applications from directly accessing hardware; applications must use OS‑provided APIs for safe access.
Summary: For applications, I/O means invoking system calls to the kernel to perform indirect I/O operations.
An application’s I/O request consists of two phases:
I/O call phase: the application issues a system call to the kernel.
I/O execution phase: the kernel performs the I/O and returns the result.
2. Blocking I/O Model
The blocking I/O model is the most common. Its flowchart is shown below.
An application calls socket.read() ; it blocks until the kernel prepares the data and copies it to user space, then returns success and the application continues processing.
Advantages: simple model, low implementation difficulty, suitable for low‑concurrency applications.
Disadvantages: both the I/O call phase and execution phase block.
Typical blocking I/O example:
data = socket.read() – if the kernel data is not ready, the thread blocks inside read() waiting for data.
Analogy: ordering a milk tea and waiting idly until it is ready, unable to do anything else.
3. Non‑Blocking I/O Model
In non‑blocking I/O, the application repeatedly polls the kernel to check whether data is ready; when data is not ready, the application can perform other work.
The diagram shows that the application must actively query the kernel for readiness.
Advantages: simple model, low implementation difficulty; unlike blocking I/O, the process is not blocked while waiting for data and can do other tasks.
Disadvantages: continuous polling (e.g., repeated recvfrom ) consumes CPU resources.
Analogy: after ordering milk tea, you wander around the mall and periodically ask the server whether the drink is ready, returning only when you finally receive confirmation.
4. I/O Multiplexing Model
Non‑blocking I/O requires many processes (or threads) to poll the kernel, which wastes resources. Instead, a single “helper” (the select system call) can monitor multiple I/O descriptors.
Analogy: a waiter (select) checks all customers’ orders; customers wait for the waiter to tell them when their drink is ready.
Answer: select acts as the intermediary that queries the kernel on behalf of many processes.
I/O multiplexing works as follows:
Multiple processes register their I/O with a selector. If no data is ready, the select call blocks. When any descriptor becomes readable, select returns, and the process performs a normal recvfrom call; the kernel then copies data to user space (this copy phase is still blocking).
Note: the I/O multiplexing model blocks both in the select call (first phase) and during data copying (second phase).
Advantages: suitable for high‑concurrency applications.
Disadvantages: more complex, higher development difficulty.
Analogy: instead of each customer repeatedly asking the kitchen, a single staff member (select) checks the kitchen and notifies the appropriate customer when their drink is ready.
Summary
When studying I/O models, it is essential to view them together: blocking I/O can cause long waits; non‑blocking I/O allows the process to continue other work while waiting for data; I/O multiplexing reduces server pressure and is advantageous when handling many connections with small messages.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.