epoll
A high-performance I/O event notification mechanism provided by the Linux kernel. It maintains state within the kernel, manages file descriptors via a red-black tree, and uses a ready-queue callback model, achieving near O(1) complexity for large-scale concurrent I/O multiplexing.
Timeline (last 90 days)
libevent wraps epoll on Linux, kqueue on BSD/macOS, uses /dev/poll or event ports on Solaris, and uses select or IOCP on Windows, and externally provides a unified event_base event loop interface.
epoll allows a single thread to monitor tens of thousands of file descriptors simultaneously, and when a socket becomes readable or writable, the kernel notifies the application to handle the corresponding event.
epoll provides two working modes: level-triggered (LT, the default) and edge-triggered (ET); ET notifies only once when a state change occurs, requiring the application to use non-blocking I/O and read all data in one go until EAGAIN
Nginx uses ET mode by default to reduce the number of epoll_wait wake-ups, and each worker process loops to read until the buffer is exhausted when handling read events
In edge-triggered mode, if only part of the data is read before returning to wait for the next notification, the remaining data will no longer trigger an event, causing a connection to appear hung
epoll implements event notification through three system calls: epoll_create, epoll_ctl, and epoll_wait
Achieving the unified capabilities of kqueue on Linux requires combining multiple APIs such as epoll, inotify, signalfd, and timerfd
epoll and kqueue follow the same philosophy: register once and wait multiple times, return only active events, and let the kernel proactively notify, making it possible for a single machine to support millions of concurrent connections
Level-triggered is more fault-tolerant and suitable for rapid development or migrating legacy code, while edge-triggered offers higher performance but makes it easier to introduce bugs—this is the trade-off between the two
Inside the kernel, epoll manages registered descriptors with a red-black tree and maintains a ready queue; the complexity of epoll_wait is close to O(1) and is only related to the number of active connections
All Facts (10)
libevent wraps epoll on Linux, kqueue on BSD/macOS, uses /dev/poll or event ports on Solaris, and uses select or IOCP on Windows, and externally provides a unified event_base event loop interface.
50%Unverifiedepoll allows a single thread to monitor tens of thousands of file descriptors simultaneously, and when a socket becomes readable or writable, the kernel notifies the application to handle the corresponding event.
50%Unverifiedepoll provides two working modes: level-triggered (LT, the default) and edge-triggered (ET); ET notifies only once when a state change occurs, requiring the application to use non-blocking I/O and read all data in one go until EAGAIN
50%UnverifiedNginx uses ET mode by default to reduce the number of epoll_wait wake-ups, and each worker process loops to read until the buffer is exhausted when handling read events
50%UnverifiedIn edge-triggered mode, if only part of the data is read before returning to wait for the next notification, the remaining data will no longer trigger an event, causing a connection to appear hung
50%Unverifiedepoll implements event notification through three system calls: epoll_create, epoll_ctl, and epoll_wait
50%UnverifiedAchieving the unified capabilities of kqueue on Linux requires combining multiple APIs such as epoll, inotify, signalfd, and timerfd
50%Unverifiedepoll and kqueue follow the same philosophy: register once and wait multiple times, return only active events, and let the kernel proactively notify, making it possible for a single machine to support millions of concurrent connections
50%UnverifiedLevel-triggered is more fault-tolerant and suitable for rapid development or migrating legacy code, while edge-triggered offers higher performance but makes it easier to introduce bugs—this is the trade-off between the two
50%UnverifiedInside the kernel, epoll manages registered descriptors with a red-black tree and maintains a ready queue; the complexity of epoll_wait is close to O(1) and is only related to the number of active connections
50%