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.
The wait() system call suspends execution of the current process until one of its children terminates. The call wait(&status) is equivalent to: waitpid(-1, &status, 0); The waitpid() system call suspends execution of the current process until a child specified by pid argument has changed state.
A call to wait() blocks the calling process until one of its child processes exits or a signal is received. After child process terminates, parent continues its execution after wait system call instruction.
BSD Process Wait FunctionsThe GNU C Library defines macros such as WEXITSTATUS so that they will work on either kind of object, and the wait function is defined to accept either type of pointer as its status-ptr argument. These functions are declared in `sys/wait.
wait(NULL) will block the parent process until any of its children has finished. If the child terminates before the parent process reaches wait(NULL) then the child process turns to a zombie process until its parent waits on it and its released from memory.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With