如何从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 

我需要做什么才能获得进程命令的输出? 我怎么能创建一个自定义线程,以便我可以完成这个?

剧本

 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 

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

嗨,来自线程#1
嗨,来自线程#2
嗨来自第3号线
嗨来自第4号线
嗨,来自第5号线

我发现使用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 

这是一种使用#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 

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

只需使用Thread#value

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