2012-09-24 28 views
5

Estoy tratando de bifurcar un subproceso, esperar a que termine, si no termina dentro de un cierto período de tiempo, mátalo.Esperando al pid de Ruby pid para salir

Esto es lo que tengo hasta ahora:

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

    Process.wait 
    puts "#{server} child exited, pid = #{pid}" 
end 

En algún lugar después de/en torno Process.wait, me gustaría algún tipo de utilidad que esperar 20 segundos, y si el proceso está todavía por ahí, yo Me gusta matarlo y marcar salida como "ERROR".

Soy nuevo en fork/exec. Mi código realmente bifurca funciona, pero simplemente no sé cómo abordar el aspecto de espera/muerte.

Respuesta

9

Uso del Timeout module: (código de 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 
+0

Esto funcionó ¡PERFECTO! – awojo

0

dará la oportunidad de subexec. Desde el archivo README:

Subexec es una biblioteca simple que genera un comando externo con un parámetro de tiempo de espera opcional. Se basa en el método Process.spawn de Ruby 1.9. Además, funciona con código síncrono y asíncrono.

Útil para bibliotecas que son envolturas de Ruby para CLI. Por ejemplo, cambiar el tamaño de las imágenes con el comando mogrify de ImageMagick a veces se detiene y nunca devuelve el control al proceso original. Ingrese Subexec.