Shall we use poll() or select()?

11,552

Solution 1

All remotely modern systems have poll, and it's a greatly superior interface to select/pselect in almost all ways:

  • poll allows more fine-grained detection of status than select.
  • poll does not have limits on the max file descriptor you can use (and more importantly, does not have critical vulnerabilities when you fail to check for file descriptors past the FD_SETSIZE limit).

The only disadvantages I can think of to using poll are that:

  • unlike pselect, poll cannot atomically unmask/mask signals, so you can't use it for waiting for a set of events that includes both file descriptor activity and signals unless you resort to the self-pipe trick.
  • poll only has millisecond resolution for the wait timeout, rather than microsecond (select) or nanosecond (pselect).

Certainly portability of poll is not a consideration anymore. Any system old enough to lack poll is full of so many vulnerabilities it should not be connected to a network.

In summary, unless you have very special needs (tiny timeout intervals, nasty signal interactions, scaling to millions of persistent connections, etc.) I would simply use poll and be done with it. As others have mentioned, libevent is also an option, but it's not clean/safe code (its use of select actually invokes dangerous UB trying to workaround the limitations of select!) and I find code that uses libevent is generally a lot more unnecessarily complicated than code that simply uses poll directly.

Solution 2

If you are writing for GNU/Linux, you should look at epoll(7).

But for most cross platform support, you could look into using libevent. http://libevent.org/

Actually, it is hard to recommend a single poll/select implementation without knowing the specifics of what you are trying to do.

Solution 3

I would actually recommend boost::asio, then you can try both implementations and test to see what suits your setup best.

Solution 4

I would use libev or libevent. These libraries are cross-platform and abstract away the details of the underlying implementation (e.g. poll, select.)

Share:
11,552
Philip
Author by

Philip

This is me. (-:

Updated on June 07, 2022

Comments

  • Philip
    Philip almost 2 years

    I'm fully aware of the major differences between poll() and select():

    • select() only supports a fixed amount of file descriptors
    • select() is supposedly supported on more systems
    • poll() allows slightly more fine-grained control of event types
    • poll() implementations may differ in certain details

    However, they both accomplish the same task in roughly the same way. So:

    Shall we use poll() or select()?


    EDIT: I might add that I'm not interested in epoll() since portability is of concern to me. Furthermore, libev(ent) is not an option either, since I'm asking this question because I'm writing my own replacement library for libev(ent).

  • NullUserException
    NullUserException over 12 years
    Pablo, you should be able to add comments now that you have over 50 reputation points. Remember to only use flags when moderator attention is needed.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 12 years
    -1 for recommending epoll. Not only is it non-portable, but it performs much worse in the (very common) situation where you're frequently adding and removing file descriptors from the list to poll since each modification operation takes a syscall and runtime is dominated by the number of syscalls. epoll is rather harmful anywhere except in gigantic-scale servers (tens or hundreds of thousands of clients) with persistent connections.
  • Remy Lebeau
    Remy Lebeau over 12 years
    I have never seen poll() available on a Windows system.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 12 years
    I've never seen select available on a Windows system either, unless you mean the broken non-conformant function by the same name in winsock...
  • Remy Lebeau
    Remy Lebeau over 12 years
    What is non-conformant about it? Other than it ignores the first parameter.
  • Jeremy Friesner
    Jeremy Friesner over 12 years
    Under Windows, select(0, NULL, NULL, NULL, &timeout) will immediately return an error code rather than sleeping for the time period specified by (timeout). Also under Windows, the failure of an asynchronous TCP connect() attempt will be reported only via FD_ISSET(sockfd, &exceptionSet) whereas on all other OS's I've seen, it gets reported via FD_ISSET(sockfd, &writeSet). It's possible to work around these differences of course, but it's annoying :)
  • dbrank0
    dbrank0 over 12 years
    Winsock if of course not posix conformant, but select is there if you need it. And also poll (since Vista, or Vista SP something). See here: msdn.microsoft.com/en-us/library/windows/desktop/…
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 12 years
    Winsock's select only works with sockets, not other kinds of file descriptors, making it rather useless...
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 12 years
    By the way, if you do find a system that lacks poll, you can emulate most of the main features of poll using select. You'll still hit the fd limit of course, but I'd opt for using a clean standard interface and emulating it in terms of a more limited interface when it's missing any day over the alternative of putting a new abstraction layer on top of them both.