Looking for a way to wait for the completion of all child processes, I found this code:
while true
p "waiting for child processes"
begin
exited_pid = Process.waitpid(-1,Process::WNOHANG)
if exited_pid and exited_pid > 0 then
p "Process exited : #{exited_pid} with status #{$?.exitstatus }"
end
sleep 5
rescue SystemCallError
puts "All children collected!"
break
end
end
This looks like it works in a similar way to Unix-systems process management, as I read on tutorialspoint HERE.
So in summary, it looks like this code:
- Calls
Process.waitpid
, for any child process that exists. If no child process has exited, continue anyway. - If a child process has exited, then notify the user. Otherwise sleep, and check again.
- When all child processes have exited an error is thrown, which is caught and the user is notified that processes are complete.
But looking at a similar question on waiting for child processes in C (Make parent wait for all child processes), which has as an answer:
POSIX defines a function: wait(NULL);. It's shorthand for waitpid(-1, NULL, 0);, which will block until all children processes exit.
I tested that Process.wait()
in Ruby achieves pretty much the same thing as the more verbose code above.
What is the benefit of the more verbose code above? Or, which is considered a better approach to waiting for child processes? It seems in the verbose code that I would be able to wait for specific processes and listen for specific exit codes. But if I don't need to do this is there any benefit?
Also, regarding the more verbose code:
- Why does the call to
Process.waitpid()
throw an error if there are no more child processes? - If more than 1 child process exists within the 5 second sleep period, it seems like there is a queue of completed processes and that
Process.waitpid
just returns the top member of the queue. What is actually happening here?