2009-09-05 43 views
26

如果我有以下代碼:如何從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 

我有什麼做的就是過程命令的輸出?我如何創建一個自定義線程,以便我可以完成此任務?

回答

42

腳本

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 
+0

Vinay,也許你也可以看看這個:http://stackoverflow.com/questions/1383470/why-is-this-running-like-it-isnt-threaded – Geo 2009-09-05 14:38:32

+2

更好地簡單地返回從輸出線程並使用'puts t.value' – Yacoby 2014-11-25 13:18:59

3

您應該使用Queue類。每個線程都應該將其結果放入隊列中,並且主線程應該從中讀取它。注意,使用這種方法,結果我的順序與隊列中的線程創建順序不同。

+2

Queue類是有用的,但對於原始海報的場景不是必需的,對於單個值或值集合沒有線程爭用。因此,在這種情況下,線程局部就足夠了。 – sheldonh 2011-10-19 07:28:23

25

我發現它易於使用收集收集線程到一個列表,並使用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 
+0

它適用於我! :) – debbie 2014-04-23 02:51:29

2

只需使用Thread#value

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

這是一個簡單而有趣的方式,使用#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