6 ms·
> epoll/kqueue are replacements for their deprecated counterparts poll and select. Neither poll nor select are deprecated. They're just not good fits for parti
by eqvinox 1y ago
> epoll/kqueue are replacements for their deprecated counterparts poll and select.
Neither poll nor select are deprecated. They're just not good fits for particular use patterns. But even select() is fine if you just need to watch 2 FDs in a CLI tool.
In fact, due to its footguns, I'd highly advise against epoll (particularly edge triggering) unless you really need it.
- MomsAVoxell 1y agoselect() is great for embedded daemons and user space signals handling, and so on. Just don't try to solve the 10,000x problem with it, by putting it on the Internet. Or, if you do, build it out properly. Or use epoll or kqueue.
- oconnor663 1y agoselect() is at least kind of deprecated, in that its own man page says not to use it in new code.
- toast0 1y agoI don't see it in the man page? https://man.freebsd.org/cgi/man.cgi?select https://man.freebsd.org/cgi/man.cgi?select The man page also suggests how you might increase the FD limit if needed. I still use select for a small number of FDs where overhead isn't a real concern, and select is a good fit.
- hippo22 1y agohttps://man7.org/linux/man-pages/man2/select.2.html https://man7.org/linux/man-pages/man2/select.2.html
- buckle8017 1y agoIn anything new you should use poll not select. They're basically identical apis but poll doesn't have a hard limit and works with high number fds.
- toast0 1y agoDoesn't seem super relevant when the program will only have 5 FDs. Safe signal handling in poll does seem handy though.
- naniwaduni 1y agoYour program can be executed with fds 0-1023 already open.
- dataflow 1y agoWhat's the footgun with edge triggering?
- buckle8017 1y agoThe edge in epoll edge triggering is going from has data to doesn't have data. So the obvious loop using level triggering switched to edge will eventually lock up. You'll read 4092bbytesbwhen there is 4093 bytes leaving 1 behind and then never get a signal again.
- HackerThemAll 1y agoThis is a blatant application bug, not an epoll issue, unless you prove otherwise.
- ahartmetz 1y agoIt is a very, very easy mistake to make though. Nothing except edge-triggered I/O multiplexing makes it a problem not to read everything you possibly could, and it is often convenient to read less and let some other part of the code handle the rest. Forgot to call that part somehow? Oops, I/O on that socket is now screwed forever.
- nly 1y agoYou just read() until it returns EWOULDBLOCK/EAGAIN before calling epoll_wait again. It's no less valid than level-triggering as a default mental model.
- ahartmetz 1y agoIt's valid, just very error-prone. An advantage of the readiness model of doing I/O over the IOCP/io_uring model is that you keep control over when, where and how much data you read. If you always have to read everything, that advantage is greatly reduced. You still have a little more control and easier memory management. Performance is generally worse vs IOCP - you should at least get some convenience for it!
- signa11 1y agoor better yet, go with libevent (https://libevent.org https://libevent.org, almost) always better than ’naked’ calls to low level routines, and cross-platform to boot.
- gritzko 1y agolubuv, libevent introduce a layer of abstraction, their own approach to buffer mgmt, etc. If poll() works, better stay with poll(). It is universally portable, things stay pretty clean and simple as a result. Right now I am working on JavaScript bindings for a project and doing it the node.js way (or Deno) is definitely a no-no. That would be one more layer in the architecture, if not two. Once you have more layers, you also have more layer interactions and that never stops. I mean, complexity begets complexity https://github.com/gritzko/librdx/blob/master/js/README.md https://github.com/gritzko/librdx/blob/master/js/README.md Having more than 1000 conns per a thread is a very specific usecase.
- HackerThemAll 1y agoVery specific, but very common, such as a web server, forward proxy, reverse proxy, load balancer, etc. Used in high millions of instances. I'd say a toy CLI tool is a very specific usecase for a lot less people than the above.
- gritzko 1y agoMore like a chat server or a sync server. Normal Web server connections are short lived. Flash crowds from HN would give 100K visits a day maybe, that is like 1 or 2 at a time unless you WebSocket them. Imagine what sort of traffic you need to saturate 1000 conns with HTTP. Can your single thread app handle it? If you are not using nginx, that must be something less trivial than a reverse proxy. Nginx can do lots of things, by the way.
- loeg 1y ago> But even select() is fine if you just need to watch 2 FDs in a CLI tool. Only if those fds are below ~1024 or whatever. (If you're going to use one of the legacy interfaces, at least poll() doesn't have arbitrary limits on the numeric value of the fd.)
- cozzyd 1y ago1024 is the default fd limit anyway, isn't it?
- saurik 1y ago...because of select, and how it became essentially impossible to ensure that a process wasn't using it anywhere, indirectly or incidentally.
- ahartmetz 1y agoThe Winsock version doesn't have this limitation. It's a very weak select() because it only works on network sockets, but it doesn't care about numeric values of file descriptors. As on POSIX, file descriptors are added and removed to the select set using macros, and these work on a vector or linked list (I forgot) instead of a bitset.
- loeg 1y agoWe’re talking about Linux/POSIX here.
- deleted 1y ago[deleted]