epoll
epoll
is a Linux system call that enables scalable I/O multiplexing. It allows
for concurrency by monitoring multiple file descriptors to see which ones are
ready for I/O operations. The POSIX predecessors for this call are select
and
poll
, but while these have O(n) performance, epoll
is O(1).
Example
A toy example that monitors stdin. A more useful program would e.g. monitor network sockets.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/epoll.h> #include <fcntl.h> #define MAX_EVENTS 10 int main() { struct epoll_event ev, events[MAX_EVENTS]; int epoll_fd = epoll_create1(0); if (epoll_fd == -1) { /* error handling */ } int server_fd = STDIN_FILENO; // stdin as file descriptor to monitor // make stdin non-blocking fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL, 0) | O_NONBLOCK); ev.events = EPOLLIN; // Monitor for input events ev.data.fd = server_fd; // add file descriptor to epoll instance if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) == -1) { perror("epoll_ctl: server_fd"); exit(EXIT_FAILURE); } printf("Monitoring stdin for input. Type something and press enter.\n"); /* event loop */ while (1) { int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); // -1 == wait indefinitely if (nfds == -1) { /* error handling */ } // Process events for (int i = 0; i < nfds; i++) { if (events[i].data.fd == server_fd) { char buffer[256]; int len = read(server_fd, buffer, sizeof(buffer) - 1); if (len > 0) { buffer[len] = '\0'; printf("Received: %s", buffer); // exit if user types "quit" if (strncmp(buffer, "quit", 4) == 0) { printf("Exiting...\n"); close(epoll_fd); exit(EXIT_SUCCESS); } } } } } close(epoll_fd); return 0; }