2009-09-05 24 views
26

Si tengo el siguiente código:¿Cómo puedo devolver un valor de un hilo en Ruby?

threads = [] 
(1..5).each do |i| 
    threads << Thread.new { `process x#{i}.bin` } 
end 
threads.each do |t| 
    t.join 
    # i'd like to get the output of the process command now. 
end 

¿Qué tengo que hacer para conseguir la salida del comando de proceso? ¿Cómo podría crear un hilo personalizado para que pueda lograr esto?

Respuesta

42

El guión

threads = [] 
(1..5).each do |i| 
    threads << Thread.new { Thread.current[:output] = `echo Hi from thread ##{i}` } 
end 
threads.each do |t| 
    t.join 
    puts t[:output] 
end 

ilustra cómo llevar a cabo lo que necesita. Tiene el beneficio de mantener el resultado con el hilo que lo generó, por lo que puede unirse y obtener la salida de cada hilo en cualquier momento. Cuando se ejecuta, las impresiones de guión

 
Hi from thread #1 
Hi from thread #2 
Hi from thread #3 
Hi from thread #4 
Hi from thread #5 
+0

Vinay, quizás también pueda ver esto: http://stackoverflow.com/questions/1383470/why-is-this-running-like-it-isnt-threaded – Geo

+2

Mucho mejor que simplemente devolver la salida de la enhebrar y usar 'puts t.value' – Yacoby

3

Debe utilizar la clase Queue. Cada hilo debe poner su resultado en la cola, y el hilo principal debe buscarlo desde allí. Tenga en cuenta que al usar ese enfoque, los resultados pueden ser diferentes del orden de creación de subprocesos en la cola.

+2

La clase Queue es útil, pero no es necesaria para el escenario del póster original, donde no hay conflicto de hilos sobre un único valor o colección de valores. Por lo tanto, los locals de hilo son suficientes en este caso. – sheldonh

25

me pareció más fácil de usar recoger a recoger los hilos en una lista, y el uso de thread.value para unirse y devolver el valor de la rosca - esto lo recorta hasta:

#!/usr/bin/env ruby 
threads = (1..5).collect do |i| 
    Thread.new { `echo Hi from thread ##{i}` } 
end 
threads.each do |t| 
    puts t.value 
end 

Cuando se ejecuta, esto produce:

Hi from thread #1 
Hi from thread #2 
Hi from thread #3 
Hi from thread #4 
Hi from thread #5 
+0

¡Funciona para mí! :) – debbie

2

sólo tiene que utilizar Thread#value:

threads = (1..5).collect do |i| 
    Thread.new { `echo x#{i}.bin` } 
end 
threads.each do |t| 
    puts t.value 
end 
7

Esta es una manera simple e interesante de usar #value() con #join() para recuperar valores de Array of threads.

a, b, c = [ 
    Thread.new { "something" }, 
    Thread.new { "something else" }, 
    Thread.new { "what?" } 
].map(&:join).map(&:value) 

puts a.inspect 
puts b.inspect 
puts c.inspect 
Cuestiones relacionadas