Search code examples
clinuxmultithreadingunixnonblocking

Analog of select() for monitoring child processes?


The select call in POSIX-compliant systems is useful when carrying out non-blocking I/O, letting one know when a file descriptor is "ready" for an I/O operation. Is there anything analogous for the waitpid system call? I know that one can use the WNOHANG flag to make an individual waitpid call non-blocking, in the same way that one can use, say, the MSG_DONTWAIT flag to make an individual recvfrom socket call non-blocking. However, sometimes the timeout feature offered by select is more convenient, and allows one to avoid a loop that repeatedly calls recvfrom as quickly as possible; select also allows one to monitor multiple file descriptors simultaneously. Is there anything offered by Unix-like systems (or Linux specifically) that gives similar functionality for monitoring child processes?


Solution

  • I'm going to expand on the possibility suggested by Craig Estey, and throw signalfd into the mix.

    Instead of setting up a signal handler to handle SIGCHLD, set up signalfd to do the job instead. That way, you'll have a file descriptor that will become ready when SIGCHLD has been signaled, and then you can use select() to wait for it, with a time out.

    I've been using signalfd as a way of catching signals for quite a while now. It's Linux specific (OK by the tags you've attached to the question!), and it's far, far easier to handle a signal in the context of the main thread of execution, instead of being limited with what one can do inside a conventional signal handler. The response time to the signal might not be quite so fast, but if an application already has a reactor such as select, or poll, or zmq_poll, or indeed any fd input to any GUI framework's event loop handler, it's an awful lot easier.