Is there a version of the wait() system call that sets a timeout?

放肆的年华 提交于 2019-11-28 01:58:56

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.

static volatile int punt;
static void sig_handler(int sig)
{
    punt = 1;
}

...

struct timeval timeout = {10,0};
int rc;

signal(SIGCHLD, sig_handler);

fork/exec stuff
//select will get interrupted by a signal

rc = select(0, NULL,NULL,NULL, &timeout ); 
if (rc == 0) {
// timed out
} else if (punt) {
    //child terminated
}

More logic is needed if you have other signal you need to handle as well though

You can use waitpid together with the WNOHANG option and a sleep.

while(waitpid(pid, &status, WNOHANG) == 0) {
    sleep(1);
}

But this will be an active sleeping. However I see no other way using the wait type of functions.

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 with select, poll, or epoll, 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 a SIGCHLD indication, you need to waitpid(-1, &status, &WNOHANG) repeatedly until it returns -1.

On FreeBSD, you can achieve the same effect rather more directly using kqueue and a kevent of type EVFILT_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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!