For child processes, the
waitpid() functions can be used to suspends execution of the current process until a child has exited. But this function can not be used for non-child processes.
Is there another function, which can wait for exit of any process ?
Nothing equivalent to
wait(). The usual practice is to poll using
kill(pid, 0) and looking for return value -1 and
ESRCH to indicate that the process is gone.
On BSDs and OS X, you can use kqueue with EVFILT_PROC+NOTE_EXIT to do exactly that. No polling required. Unfortunately there’s no Linux equivalent.
So far I’ve found three ways to do this on Linux:
- Polling: you check for the existence of the process every so often, either by using
killor by testing for the existence of
/proc/$pid, as in most of the other answers
- Use the
ptracesystem call to attach to the process like a debugger so you get notified when it exits, as in a3nm’s answer
- Use the
netlinkinterface to listen for
PROC_EVENT_EXITmessages – this way the kernel tells your program every time a process exits and you just wait for the right process ID. I’ve only seen this described in one place on the internet.
Shameless plug: I’m working on a program (open source of course; GPLv2) that does any of the three.
You could also create a socket or a FIFO and read on them. The FIFO is especially simple: Connect the standard output of your child with the FIFO and read. The read will block until the child exits (for any reason) or until it emits some data. So you’ll need a little loop to discard the unwanted text data.
If you have access to the source of the child, open the FIFO for writing when it starts and then simply forget about it. The OS will clean the open file descriptor when the child terminates and your waiting “parent” process will wake up.
Now this might be a process which you didn’t start or own. In that case, you can replace the binary executable with a script that starts the real binary but also adds monitoring as explained above.
You could attach to the process with
ptrace(2). From the shell,
strace -p PID >/dev/null 2>&1 seems to work. This avoid the busy-waiting, though it will slow down the traced process, and will not work on all processes (only yours, which is a bit better than only child processes).
None I am aware of. Apart from the solution from chaos, you can use semaphores if you can change the program you want to wait for.
The library functions are
sem_wait(3) performs a wait, so you don´t have to do busy waiting as in chaos´ solution. Of course, using semaphores makes your programs more complex and it may not be worth the trouble.
Maybe it could be possible to wait for /proc/[pid] or /proc/[pid]/[something] to disappear?
There are poll() and other file event waiting functions, maybe that could help?