I have an executable file that, when run, creates child processes and then terminates. I want to track the total execution time, including when all its child processes have finished. If I simply use time my_process
, it returns immediately with the execution time of the parent process. Is there a way to solve this?
3
I found a solution based on this answer. The idea is to open a file, which will be inherited by all child processes, and then wait until that file is no longer in use. So, basically I wrote the following script (my_script.sh
):
#!/bin/bash
foo=$(mktemp)
( flock -x 500; ./my_process; ) 500> "$foo"
flock -x 0 < "$foo"
rm "$foo"
I can now run time ./my_script.sh
.
Processes by default will belong to the same process group as their parent; process group membership doesn’t change even if the parent process dies. The shell creates a new process group for each process, so what we can do is to wait on the process group. To do this:
./my_process &
pgrp=-$!
while kill -0 $pgrp 2>/dev/null; do
sleep 1
done
The magic is in the kill
command. -0
means to send signal 0, which simply checks to see if the process is alive. -$!
gets the PID of the target process as a PGID (negating the PID); killing a PGID will succeed as long as there is at least one process still in the group.
For example, if we use (bash -c 'sleep 5 & sleep 10 &')
for ./my_process
, the wrapping bash
will exit right away, but the script above will wait 10 seconds for the last sleep
command to exit.
1