How do I use non-blocking I/O and epoll/kqueue?

Non-blocking I/O allows a program to operate without waiting for operations like file or network I/O to complete. This is particularly useful in high-performance server applications where responsiveness is key. In Linux, `epoll` is a scalable I/O event notification system. Similarly, in BSD systems, `kqueue` provides similar functionality. Both allow handling many connections efficiently.

non-blocking I/O, epoll, kqueue, I/O multiplexing, performance

This article covers how to implement non-blocking I/O using epoll and kqueue for high-performance applications.

 
// Example of using epoll in a C++ application
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>

int setNonBlocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

int main() {
    int epfd = epoll_create1(0);
    struct epoll_event ev;
    
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    setNonBlocking(listen_fd);
    
    // Setup listen socket and bind...
    
    ev.events = EPOLLIN;
    ev.data.fd = listen_fd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev);

    while (true) {
        struct epoll_event events[10];
        int n = epoll_wait(epfd, events, 10, -1);
        
        for (int i = 0; i < n; i++) {
            if (events[i].data.fd == listen_fd) {
                // Accept new connection...
            } else {
                // Handle data...
            }
        }
    }
    
    close(epfd);
    return 0;
}
    

non-blocking I/O epoll kqueue I/O multiplexing performance