Epoll Trigger Mode
In Linux, epoll
is a high-performance I/O event notification system
that allows the application to monitor multiple file descriptors to
determine if I/O operations can be performed on any of them.
There are two trigger modes: Level-Triggered (default) and Edge-Triggered.
Level-Triggered (LT)
In level-triggered mode (the default mode for epoll
), the application is
notified about an event as long as the condition persists (e.g. a fd remains
ready for reading or writing). This means that if there is data available
to read or buffer ready to write, epoll
will continue to notify the
application repeatedly until the condition changes, such as when all the
data has been read or the buffer is full.
#include <sys/epoll.h>
struct epoll_event ev;
ev.events = EPOLLIN; // level-triggered (default), input events
ev.data.fd = fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
This mode is easier to use because the application doesn't risk missing events, even if it doesn't process them immediately. However, it can lead to redundant notifications, which might reduce performance in scenarios involving frequent and high-volume events.
Edge-Triggered (ET)
In edge-triggered mode, epoll
notifies the application about an event only
when the state changes (e.g. from not-ready to ready). Once notified, the
application must handle the event completely, such as reading all available data
or writing all buffered data, because no further notifications will be sent for
the same state.
#include <sys/epoll.h>
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET; // edge-triggered, input events
ev.data.fd = fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
When using non-blocking I/O, if the operation cannot proceed immediately (e.g.
there is no more data to read or the output buffer is full), the system call will
return EAGAIN
. The application must continue processing in a loop until EAGAIN
is encountered, ensuring that all data is handled. Failure to do so can result in
unprocessed data being left unread or unwritten, with no further notifications,
potentially causing the application to miss critical events.
// non-blocking mode
ssize_t n;
while ((n = read(fd, buffer, buffer_size)) > 0) {
// process the data
}
if (n == -1 && errno != EAGAIN) {
perror("read error")
}
Edge-Triggered mode is best used in high-performance applications that handle many file descriptors, such as servers or real-time systems, where reducing notification overhead and improving efficiency is crucial. It’s ideal when you need to minimize the number of system calls and notifications. However, ET requires careful event handling, ensuring that events are fully processed and non-blocking I/O is used, as further notifications won’t be sent unless the state changes.