@Suiseiseki @marcelschmall

> Is it really that impressive [...]

Yes. Because spawning a thread is much heavier than waiting for `POLLIN | POLLOUT`.

Spawning a thread just to handle a single fd is definitely not resource-wise; you need a dedicated stack, a tid, scheduling parameters, I/O prio, a dedicated PCB, and so many other scheduling-related resources.

@Suiseiseki @marcelschmall

Before epoll was invented, there were already select() and poll() to handle multiple fds with a single process, but poll()'s interface wasn't very efficient because you had to traverse all the `struct pollfd` array members for each sysret.

If you have 10K connections and one connection sends you data, with poll(), you need to traverse up to 10K `struct pollfds` to find which connection sends you data.

select() is even worse; it can only handle up to `FD_SETSIZE` number of fds which is defined as 1024. The traversal is pretty much the same as poll().

epoll solves the problem by avoiding wasted iterations in the caller for iterating over connections.

@Suiseiseki @marcelschmall

Additionally, since Linux 5.1, we have io_uring, which offers advantages over epoll, such as better performance and more I/O operations.

#io_uring

@Suiseiseki @marcelschmall

But I think you should use io_uring with kernel 6.x+ to actually see how useful it is for various workloads. I'm not confident using io_uring on 5.x kernels.