Is there any way to use the wait()
system call with a timeout, besides using a busy-waiting or busy-sleeping loop?
I've got a parent process that fork
s itself and exec
s a child executable. It then waits for the child to finish, grabs its output by whatever means appropriate, and and performs further processing. If the process does not finish within a certain period of time, it assumes that its execution timed out, and does something else. Unfortunately, this timeout detection is necessary given the nature of the problem.
On linux, you can also solve this problem using
signalfd
.signalfd
essentially takes a set of signals and creates an fd which you can read; each block you read corresponds to a signal which has fired. (You should block these signals with sigprocmask so that they are not actually sent.)The advantage of
signalfd
is that you can use the fd withselect
,poll
, orepoll
, all of which allow for timeouts, and all of which allow you to wait for other things as well.One note: If the same signal fires twice before the corresponding
struct signalfd_siginfo
is read, you'll only receive a single indication. So when you get aSIGCHLD
indication, you need towaitpid(-1, &status, &WNOHANG)
repeatedly until it returns -1.On FreeBSD, you can achieve the same effect rather more directly using
kqueue
and akevent
of typeEVFILT_PROC
. (You can also kqueue a SIGCHLD event, but EVFILT_PROC lets you specify the events by child pid instead of globally for all children.) This should also work on Mac OS X, but I've never tried it.There's not a wait call that takes a timeout.
What you can do instead is install a signal handler that sets a flag for SIGCHLD, and use select() to implement a timeout. select() will be interrupted by a signal.
More logic is needed if you have other signal you need to handle as well though
You can use
waitpid
together with theWNOHANG
option and a sleep.But this will be an active sleeping. However I see no other way using the
wait
type of functions.