Understanding Linux I/O Models: Blocking, Non‑Blocking, and Multiplexing Explained
This article explains core Linux I/O concepts—including synchronous vs. asynchronous operations, blocking vs. non‑blocking behavior, user and kernel space separation, process switching, file descriptors, cache I/O, and the differences among select, poll, and epoll—providing a comprehensive overview for developers.
1. Related Concepts Explanation
1.1 Synchronous and Asynchronous
Synchronous execution requires a task to wait for its dependent task to finish before it can be considered complete, forming a reliable sequence where success or failure is consistent across tasks.
Asynchronous execution does not wait for the dependent task; it merely notifies the dependent task of the work to be done, allowing the notifying task to finish immediately. The dependent task’s final state is uncertain, making the sequence unreliable.
1.2 Blocking and Non‑Blocking
Blocking and non‑blocking describe the state of a program (or thread) waiting for a message notification, regardless of whether the operation is synchronous or asynchronous.
Blocking calls suspend the current thread until the result is returned; the thread cannot perform other work during this wait.
Non‑blocking calls return immediately if the result is not ready, allowing the thread to continue execution. Although this can improve CPU utilization, it may increase thread‑switch overhead.
(a) When a thread continues processing other messages while waiting, it is called synchronous non‑blocking . (b) When a thread is suspended and does not process other messages, it is called synchronous blocking .
Key distinction: Synchronous/asynchronous concerns the notification mechanism, while blocking/non‑blocking concerns the thread’s waiting state.
1.3 User Space and Kernel Space
In a 32‑bit OS with virtual memory, the address space is 4 GB. The upper 1 GB (0xC0000000–0xFFFFFFFF) is reserved for the kernel (kernel space), and the lower 3 GB (0x00000000–0xBFFFFFFF) is for user processes (user space).
1.4 Process Switching
The kernel can suspend a running process and resume a previously suspended one. A context switch involves:
Saving the CPU context (program counter and registers).
Updating the PCB (process control block).
Moving the PCB to the appropriate queue (ready, blocked, etc.).
Selecting another process to run and updating its PCB.
Updating memory‑management structures.
Restoring the CPU context.
This operation is resource‑intensive.
1.5 Process Blocking
A running process may become blocked when it awaits an event such as a resource request, I/O completion, or new data. Blocking is initiated by the system and does not consume CPU resources while the process is in the blocked state.
1.6 File Descriptors
A file descriptor is a non‑negative integer that serves as an index into the kernel‑maintained table of open files for a process. It is primarily used in UNIX‑like systems (Linux).
1.7 Cache I/O
Cache I/O (standard I/O) copies data first into the kernel’s page cache, then from the cache to the user‑space address space. This double copy incurs CPU and memory overhead.
2. I/O Models
Network I/O is essentially socket reads, abstracted as streams in Linux. An I/O operation proceeds in two stages: waiting for data to be ready, then copying data from kernel to user space.
2.1 Blocking I/O Model
The application calls an I/O function and blocks until data is ready. For example, recv() waits for data; if none is available, the call blocks until the kernel copies data to user space and returns success.
2.2 Non‑Blocking I/O Model
Setting a socket to non‑blocking tells the kernel to return an error instead of sleeping when the operation cannot complete. The application must repeatedly poll the socket, which can waste CPU cycles and is generally discouraged.
2.3 I/O Multiplexing Model
Multiplexing (e.g., select, poll, epoll) allows a single thread to monitor multiple sockets and be notified when any become ready, avoiding continuous polling.
These system calls can block the process, but unlike pure blocking I/O they unblock only when at least one monitored descriptor is ready, reducing unnecessary waiting.
2.4 Signal‑Driven I/O
By installing a signal handler for SIGIO, a process can continue running while the kernel notifies it via a signal when data is ready, allowing the process to perform I/O without blocking.
2.5 Asynchronous I/O Model
With asynchronous I/O, a process issues an aio_read (or similar) and returns immediately. The kernel completes the operation independently and notifies the process when the data is ready, eliminating the need for the process to poll or copy data manually.
Linux provides the AIO library, though it is rarely used; popular user‑space libraries include libevent, libev, and libuv.
2.6 Comparison of Five I/O Models
The main differences lie in the waiting time and data‑copy phases. Non‑blocking I/O reduces blocking time but requires active polling, while asynchronous I/O delegates both waiting and copying to the kernel, allowing the process to perform other work uninterrupted.
3. Differences Among select, poll, and epoll
Key considerations include the maximum number of connections a process can handle, the impact of a large number of file descriptors on I/O efficiency, and the message‑delivery mechanisms.
When choosing between them, epoll often offers the best performance for high‑connection, low‑activity scenarios, while select or poll may be faster for a small number of active connections due to lower overhead.
Both select and poll are level‑triggered; signal‑driven I/O is edge‑triggered; epoll supports both, defaulting to level‑triggered.
Level‑triggered: epoll_wait() notifies as long as data remains unread; repeated calls continue to notify until the data is fully consumed.
Edge‑triggered: epoll_wait() notifies only on the transition from no data to data available; if the application does not read all data, it will not be notified again until new data arrives.
Source: Architecture Technical Alliance
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
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.
