Reputation: 96887
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?
Upvotes: 45
Views: 20018
Reputation: 127497
You should use the Queue class. Each thread should put its result in the queue, and the main thread should fetch it from there. Notice that using that approach, results my be in a order different from thread creation order in the queue.
Upvotes: 3
Reputation: 4193
This is a simple, and interesting way to use Thread#value:
a, b, c = [
Thread.new { "something" },
Thread.new { "something else" },
Thread.new { "what?" }
].map(&:value)
a # => "something"
b # => "something else"
c # => "what?"
Upvotes: 23
Reputation: 2989
Just use Thread#value
:
threads = (1..5).collect do |i|
Thread.new { `echo x#{i}.bin` }
end
threads.each do |t|
puts t.value
end
Upvotes: 3
Reputation: 2047
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
Upvotes: 41
Reputation: 99405
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
Upvotes: 58