Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 forks itself and execs 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.

like image 597
alexgolec Avatar asked Aug 27 '13 21:08

alexgolec


People also ask

What is the function of wait () system call?

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.

Does wait () wait for all child processes?

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.

What library is wait () in C?

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.

What does wait null do?

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.


2 Answers

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

like image 173
nos Avatar answered Nov 15 '22 10:11

nos


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.

like image 28
hek2mgl Avatar answered Nov 15 '22 09:11

hek2mgl