如何从Ruby中的线程返回值?

时间:2009-09-05 14:08:51

标签: ruby multithreading

如果我有以下代码:

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

如何获取流程命令的输出?我怎么能创建一个自定义线程,以便我可以完成这个?

5 个答案:

答案 0 :(得分:44)

脚本

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

说明了如何完成您的需求。它的好处是保持输出与生成它的线程,因此您可以随时加入并获取每个线程的输出。运行时,脚本打印

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

答案 1 :(得分:28)

我发现使用collect将Threads收集到列表中更简单,并使用thread.value连接并从线程返回值 - 这将其修剪为:

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

运行时,会产生:

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

答案 2 :(得分:11)

这是一种使用#value()#join()从线程数组中检索值的简单而有趣的方法。

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

答案 3 :(得分:3)

只需使用Thread#value

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

答案 4 :(得分:2)

您应该使用Queue课程。每个线程都应该将其结果放入队列中,主线程应该从那里获取它。请注意,使用该方法,结果我的顺序与队列中的线程创建顺序不同。