Variable compartida entre procesos Ruby
process shared-objects (4)
Tengo un programa de Ruby que carga dos archivos yaml muy grandes, por lo que puedo acelerar un poco aprovechando los múltiples núcleos mediante el bloqueo de algunos procesos. Intenté buscar, pero tengo problemas para calcular cómo, o incluso si puedo compartir variables en diferentes procesos.
El siguiente código es el que tengo actualmente:
@proteins = ""
@decoyProteins = ""
fork do
@proteins = YAML.load_file(database)
exit
end
fork do
@decoyProteins = YAML.load_file(database)
exit
end
p @proteins["LVDK"]
P
muestra nil debido a la horquilla.
Entonces, ¿es posible que los procesos bifurcados compartan las variables? Y si es así, ¿cómo?
Es posible compartir variables entre procesos; DRuby es probablemente la forma más sencilla de barrera a la entrada para hacerlo.
Es probable que desee utilizar un hilo en lugar de un tenedor si desea compartir datos.
http://ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html
Ah, y si realmente quieres aprovechar los hilos, querrás usar JRuby. En [c] Ruby 1.9, es posible que siempre quiera echar un vistazo a las fibras. Aunque no los he visto, no sé si es una solución para ti.
Un problema es que necesita utilizar Process.wait
para esperar a que se completen sus procesos bifurcados. La otra es que no se puede hacer comunicación entre procesos a través de variables. Para ver esto:
@one = nil
@two = nil
@hash = {}
pidA = fork do
sleep 1
@one = 1
@hash[:one] = 1
p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ]
end
pidB = fork do
sleep 2
@two = 2
@hash[:two] = 2
p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :two => 2 } ]
end
Process.wait(pidB)
Process.wait(pidA)
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, nil, :two, nil, :hash, {} ]
Una forma de hacer comunicación entre procesos es usar una tubería ( IO::pipe
). Ábrelo antes de hornear, luego haz que cada lado del tenedor cierre un extremo de la tubería.
De ri IO::pipe
:
rd, wr = IO.pipe
if fork
wr.close
puts "Parent got: <#{rd.read}>"
rd.close
Process.wait
else
rd.close
puts "Sending message to parent"
wr.write "Hi Dad"
wr.close
end
_produces:_
Sending message to parent
Parent got: <Hi Dad>
Si quiere compartir variables, use hilos:
@one = nil
@two = nil
@hash = {}
threadA = Thread.fork do
sleep 1
@one = 1
@hash[:one] = 1
p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ] # (usually)
end
threadB = Thread.fork do
sleep 2
@two = 2
@hash[:two] = 2
p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :one => 1, :two => 2 } ] # (usually)
end
threadA.join
threadB.join
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, 1, :two, 2, :hash, { :one => 1, :two => 2 } ]
Sin embargo, no estoy seguro de si enhebrar obtendrá alguna ganancia cuando esté vinculado a IO.
Cod está diseñado para la comunicación entre procesos y le permitirá enviar datos fácilmente entre procesos bifurcados.