metodos - operador modulo ruby
¿Cómo se genera un proceso secundario en Ruby? (5)
Quiero descargar un bloque de código en mi proceso principal al proceso secundario para que se ejecute al mismo tiempo. También quiero tener el PID del proceso hijo engendrado para poder controlarlo y matarlo si es necesario.
Puede usar el método de kernel de fork
. Aquí hay un ejemplo:
#!/usr/bin/env ruby
puts "This is the master process."
child_pid = fork do
puts "This is the child process"
exit
end
puts "The PID of the child process is #{child_pid}"
El método fork
devuelve el PID del proceso que bifurca y ejecuta cualquier código en el bloque pasado. Al igual que los bloques regulares de Ruby, mantiene los enlaces del proceso principal.
Es una buena idea exit
proceso bifurcado.
Si está contento de utilizar Threads, en lugar de Process, entonces algo como esto puede ser un poco más escalable a fork más de uno:
def doit(x)
sleep(rand(10))
puts "Done... #{x}"
end
thingstodo = ["a","b","c","d","e","f","g"]
tasklist = []
# Set the threads going
thingstodo.each { |thing|
task = Thread.new(thing) { |this| doit(this) }
tasklist << task
}
# Wait for the threads to finish
tasklist.each { |task|
task.join
}
Consulte los excelentes comentarios y referencias de John Topley, a continuación, sobre el modelo de ejecución de Ruby y sus restricciones.
Recién editado para corregir un error evidente (sin asignación a la tarea), y para seguir el consejo de @ (Jason King).
En 1.9 puede usar el comando Process.spawn. Ver también http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes
Una buena alternativa a fork / exec / spawn es la gema posix-spawn para Ruby 1.9: https://github.com/rtomayko/posix-spawn
Hicieron la mayor parte del trabajo duro para hacerlo más fácil, eficiente y flexible en comparación con los métodos de nivel inferior.
Además de la gran respuesta de Chris, recuerde llamar a Process.wait
de su maestro para cosechar el proceso de su hijo, de lo contrario dejará zombies atrás.
Ejemplo como se solicita en los comentarios:
pid = Process.fork do
puts "child, pid #{Process.pid} sleeping..."
sleep 5
puts "child exiting"
end
puts "parent, pid #{Process.pid}, waiting on child pid #{pid}"
Process.wait
puts "parent exiting"