Skip to content

Instantly share code, notes, and snippets.

@MangaD
Created February 9, 2025 18:19
Show Gist options
  • Select an option

  • Save MangaD/a16e7e4caadb5427fd3b3e37c4d41ed4 to your computer and use it in GitHub Desktop.

Select an option

Save MangaD/a16e7e4caadb5427fd3b3e37c4d41ed4 to your computer and use it in GitHub Desktop.
`select()` vs `poll()` vs `epoll()` in C/C++

select() vs poll() vs epoll() in C/C++

CC0

Disclaimer: ChatGPT generated document.

Here's a comparison of select(), poll(), and epoll(), focusing on their differences, advantages, and disadvantages.


1. select() vs poll() vs epoll() – Overview

Feature select() poll() epoll()
Introduction Oldest, POSIX Newer, POSIX Linux-specific
Max FD Limit Limited by FD_SETSIZE (often 1024) No limit (depends on system) No limit (depends on system)
Efficiency O(n) (scans all FDs) O(n) (scans all FDs) O(1) (event-driven)
Memory Usage Uses fixed fd_set (bitmask) Uses an array of pollfd structs Uses an efficient kernel structure
State Persistence Needs to be reinitialized on every call Needs to be reinitialized on every call Persistent: Kernel keeps track of watched FDs
Best Use Case Small number of FDs Small to medium number of FDs Large-scale applications

2. poll() – The Successor of select()

Function Prototype

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

How it Works

  • Uses an array of pollfd structs, instead of a bitmask.
  • nfds is the number of file descriptors to check.
  • timeout can be:
    • 0 → Non-blocking.
    • -1 → Block indefinitely.
    • Custom time in milliseconds.

Example: Monitoring stdin

#include <stdio.h>
#include <poll.h>
#include <unistd.h>

int main() {
    struct pollfd fds;
    fds.fd = 0; // stdin
    fds.events = POLLIN; // Wait for input

    int timeout = 5000; // 5 seconds
    printf("Waiting for input...\n");

    int result = poll(&fds, 1, timeout);

    if (result == -1) {
        perror("poll");
    } else if (result == 0) {
        printf("Timeout: No input received.\n");
    } else {
        if (fds.revents & POLLIN) {
            printf("Data is available on stdin!\n");
        }
    }

    return 0;
}

Advantages of poll() Over select()

✅ No FD_SETSIZE limit.
✅ Uses an array instead of a bitmask, making it more flexible.
✅ Supports more event types, like POLLIN, POLLOUT, POLLERR.

Disadvantages

O(n) complexity, still inefficient for large FDs.
❌ Must reinitialize pollfd array every call.


3. epoll() – The Efficient Linux Solution

🔹 Linux-specific (not available on macOS, BSD, or Windows)
🔹 Best for high-performance, large-scale applications (e.g., web servers, databases, chat apps)

Function Prototypes

#include <sys/epoll.h>

int epoll_create1(int flags);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

How it Works

  1. Create an epoll instance

    int epfd = epoll_create1(0);
  2. Add, modify, or remove FDs from the epoll set.

    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = sockfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
  3. Wait for events

    struct epoll_event events[10];
    int num_events = epoll_wait(epfd, events, 10, -1);

Example: Monitoring stdin

#include <stdio.h>
#include <sys/epoll.h>
#include <unistd.h>

int main() {
    int epfd = epoll_create1(0);
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = 0; // stdin

    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev);

    printf("Waiting for input...\n");
    struct epoll_event events[1];

    int result = epoll_wait(epfd, events, 1, 5000); // 5s timeout

    if (result == -1) {
        perror("epoll_wait");
    } else if (result == 0) {
        printf("Timeout: No input received.\n");
    } else {
        printf("Data is available on stdin!\n");
    }

    close(epfd);
    return 0;
}

Advantages of epoll()

O(1) complexity → Handles large numbers of FDs efficiently.
Event-driven → Doesn't scan all FDs like select()/poll().
Persistent state → Kernel tracks monitored FDs.

Disadvantages

Linux-only.
❌ More complex API than select()/poll().
❌ Not as portable as poll().


4. Summary: When to Use Each

Use Case Best Choice
Small number of FDs (≤1024) select() or poll()
Medium number of FDs (~few thousand) poll()
Large number of FDs (e.g., web servers) epoll() (Linux-only)

Would you like a deeper dive into epoll() with edge-triggered vs level-triggered modes? 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment