Question

How can I return a value from a thread in Ruby?

If I have the following code :

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

What do I have to do to get the output of the process command? How could I create a custom thread so that I can accomplish this?

 45  19527  45
1 Jan 1970

Solution

 57

The 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

illustrates how to accomplish what you need. It has the benefit of keeping the output with the thread that generated it, so you can join and get the output of each thread at any time. When run, the script prints

Hi from thread #1
Hi from thread #2
Hi from thread #3
Hi from thread #4
Hi from thread #5
2009-09-05

Solution

 41

I found it simpler to use collect to collect the Threads into a list, and use thread.value to join and return the value from the thread - this trims it down to:

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

When run, this produces:

Hi from thread #1
Hi from thread #2
Hi from thread #3
Hi from thread #4
Hi from thread #5
2014-04-09