Why select and poll Fall Behind epoll: A Deep Dive into Linux I/O Multiplexing
This article compares Linux's select, poll, and epoll mechanisms, explaining their internal workings, limitations such as FD_SETSIZE and linear scanning, and why epoll's event‑driven design offers superior scalability and performance for high‑concurrency network servers.
1. select
select works by setting or checking a data structure that holds fd flags, which limits the number of file descriptors a single process can monitor (FD_SETSIZE, typically 1024 on 32‑bit and 2048 on 64‑bit systems). The limit can be viewed with cat /proc/sys/fs/file-max, but increasing it requires kernel recompilation and may affect performance.
Drawbacks include:
Limited number of monitorable fds per process.
Linear scanning of all fds on each call, leading to O(n) overhead as the number of sockets grows.
Every select invocation copies the fd set from user space to kernel space, incurring significant copy cost when many fds are present.
2. poll
poll is similar to select but uses an array of pollfd structures instead of an fd_set, removing the hard FD_SETSIZE limit. However, poll still copies the entire fd array between user and kernel space and scans each entry, so its overhead also grows linearly with the number of fds.
The kernel copies the user‑provided array into kernel space.
It then checks each fd's status; if no fd is ready, the process is suspended until an event occurs or a timeout expires, causing repeated useless scans.
3. epoll
epoll implements true event‑driven I/O. Applications register fds with epoll_ctl; when an fd becomes ready, the kernel notifies the process via epoll_wait. This reduces complexity to O(1) and eliminates the FD_SETSIZE limitation.
3.1 Trigger Modes
LT (Level‑Triggered) : The default mode; as long as data remains readable, each epoll_wait returns the event.
ET (Edge‑Triggered) : Notifies only once when new data arrives; the application must read until read returns EAGAIN or fewer bytes than requested.
3.2 Advantages
No hard limit on concurrent connections; the number of open fds can reach hundreds of thousands on a gigabyte of memory.
Only active fds generate callbacks, so performance does not degrade with the total number of fds.
Uses mmap to share memory between kernel and user space, reducing copy overhead.
4. Summary
select, poll, and epoll all provide I/O multiplexing, but select and poll suffer from linear scanning and fd limits, while epoll offers scalable, event‑driven handling with O(1) complexity. In low‑connection, highly active scenarios, select or poll may be slightly faster, but for high‑concurrency servers epoll is generally superior.
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.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
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.
