2009-09-05 17 views
26

Se ho il seguente codice:Come posso restituire un valore da un thread in 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 

Che cosa devo fare per ottenere l'output del comando processo? Come posso creare un thread personalizzato in modo che io possa realizzare questo?

risposta

42

Lo script

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 

illustra come realizzare ciò che vi serve. Ha il vantaggio di mantenere l'output con il thread che lo ha generato, così puoi unirti e ottenere l'output di ogni thread in qualsiasi momento. Quando viene eseguito, le stampe di script

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

Vinay, forse puoi dare un'occhiata anche a questo: http://stackoverflow.com/questions/1383470/why-is-this-running-like-it-isnt-threaded – Geo

+2

Molto più semplice restituire semplicemente l'output dal thread e usa 'puts t.value' – Yacoby

3

È necessario utilizzare la classe Queue. Ogni thread dovrebbe mettere i suoi risultati in coda e il thread principale dovrebbe recuperarlo da lì. Si noti che utilizzando tale approccio, i risultati sono in un ordine diverso dall'ordine di creazione dei thread nella coda.

+2

La classe Queue è utile, ma non necessario per lo scenario del manifesto originale, dove non c'è contesa filo sopra un singolo valore o un insieme di valori. Pertanto, in questo caso, i locatori di thread sono sufficienti. – sheldonh

25

ho trovato più semplice da usare per raccogliere raccogliere le discussioni in una lista, e utilizzare thread.value ad aderire e restituire il valore dal thread - questo trim verso il basso per:

#!/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 

Quando viene eseguito, questo produce:

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

Funziona per me! :) – debbie

2

Basta usare Thread#value:

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

Questo è un modo semplice e interessante per utilizzare #value() con #join() per recuperare i valori dalla matrice di thread.

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 
Problemi correlati