Asynchronous IO with epoll and kqueue
Scale to many connections with epoll on Linux and kqueue on BSD or macOS.
Asynchronous IO with epoll and kqueue is a free C++ Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Async I/O?
A thread per connection does not scale to thousands or millions of clients. Async I/O lets one thread handle many sockets by waiting for any of them to become readable or writable.
Linux: epoll
Linux s scalable event API. Add file descriptors to an epoll instance; wait for events on any of them.
#include <sys/epoll.h>
int epfd = epoll_create1(0);
epoll_event ev{};
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);Waiting for Events
epoll_wait blocks until events are available, then returns the ready descriptors.
epoll_event events[64];
int n = epoll_wait(epfd, events, 64, -1);
for (int i = 0; i < n; ++i) {
int fd = events[i].data.fd;
handle_io(fd);
}Edge-Triggered vs Level-Triggered
Two modes:
- Level-triggered (default) — epoll keeps reporting while a condition holds
- Edge-triggered (
EPOLLET) — reports only on state change; you must drain the socket fully each time
macOS and BSD: kqueue
kqueue is the BSD equivalent of epoll, also available on macOS. Conceptually similar; different API.
#include <sys/event.h>
int kq = kqueue();
struct kevent ev;
EV_SET(&ev, sock, EVFILT_READ, EV_ADD, 0, 0, nullptr);
kevent(kq, &ev, 1, nullptr, 0, nullptr);Windows: IOCP
Windows uses I/O Completion Ports (IOCP) — a completion-based model (notify when done) rather than the readiness model of epoll/kqueue.
Non-Blocking Sockets
Set sockets to non-blocking with fcntl(fd, F_SETFL, O_NONBLOCK). Otherwise reads and writes can block the entire event loop.
The Event Loop Pattern
A loop that runs forever:
- Wait for ready events
- For each event, perform I/O until it would block
- Repeat
Handling Many Clients
A single epoll thread can handle tens of thousands of concurrent connections — the C10K problem. Modern systems push to millions.
Common Pitfalls
Watch out for:
- Forgetting to set non-blocking mode
- Edge-triggered without draining the socket
- Not removing closed FDs from the epoll set
- Buffer leaks per connection
Higher-Level Wrappers
Writing an epoll loop by hand is error-prone. Use libuv, libevent, or Boost.Asio for production code — they abstract platform differences and provide tested I/O loops.
Async vs Threads
Async I/O is more scalable but harder to write. For low-thousand-connection servers, a thread-per-connection model is simpler. Choose based on the load you expect.
Quick Check
What is the difference between edge-triggered and level-triggered modes in epoll?
Recap
Async I/O scales to massive concurrency by handling many sockets in one thread. Linux uses epoll, BSD/macOS use kqueue, Windows uses IOCP. Set sockets non-blocking. For production, use a library (Asio, libuv, libevent) instead of hand-coding the event loop.
Frequently asked questions
Is the “Asynchronous IO with epoll and kqueue” lesson free?
Yes — the full text of “Asynchronous IO with epoll and kqueue” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.
What will I learn in “Asynchronous IO with epoll and kqueue”?
Scale to many connections with epoll on Linux and kqueue on BSD or macOS. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C++ Academy?
No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Asynchronous IO with epoll and kqueue” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C++ Academy lesson?
Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- BSD Sockets API in C++
- Building a TCP Echo Server
- Asynchronous IO with epoll and kqueue
- Using Boost Asio for Modern Async IO