Waiting for Ruby Child Pid to Exit

Waiting for Ruby child pid to exit

Use the Timeout module: (code from http://www.whatastruggle.com/timeout-a-subprocess-in-ruby)

require 'timeout'

servers.each do |server|
pid = fork do
puts "Forking #{server}."
output = "doing stuff here"
puts output
end

begin
Timeout.timeout(20) do
Process.wait
end
rescue Timeout::Error
Process.kill 9, pid
# collect status so it doesn't stick around as zombie process
Process.wait pid
end
puts "#{server} child exited, pid = #{pid}"
end

Ruby: wait for any child process to finish

Just call

Process.wait

With no arguments. This waits for any child process to terminate (see docs

You can also wait for children of a specific process group - possibly useful if you need more control.

How do get exit code from Ruby's Process.fork()?

From the manual for fork:

The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.

So in your case:

Process.wait(pid).exitstatus

Threads are a completely different thing than a multi-process model. If you're writing parallel code you'll need to determine what your best approach is.

Kill a Ruby child process when another Ruby child process has completed

Just add Process.wait(pid_logcat) after your code.

Fork child process with timeout and capture output

You can use IO.pipe and tell Process.spawn to use the redirected output without the need of external gem.

Of course, only starting with Ruby 1.9.2 (and I personally recommend 1.9.3)

The following is a simple implementation used by Spinach BDD internally to capture both out and err outputs:

# stdout, stderr pipes
rout, wout = IO.pipe
rerr, werr = IO.pipe

pid = Process.spawn(command, :out => wout, :err => werr)
_, status = Process.wait2(pid)

# close write ends so we could read them
wout.close
werr.close

@stdout = rout.readlines.join("\n")
@stderr = rerr.readlines.join("\n")

# dispose the read ends of the pipes
rout.close
rerr.close

@last_exit_status = status.exitstatus

The original source is in features/support/filesystem.rb

Is highly recommended you read Ruby's own Process.spawn documentation.

Hope this helps.

PS: I left the timeout implementation as homework for you ;-)



Related Topics



Leave a reply



Submit