2012-08-01 93 views
3

我已經開始關注Ruby中的多線程。所以基本上,我想創建幾個線程,並讓它們全部執行,但是在線程成功完成之前不顯示任何輸出。Ruby多線程問題

實施例:

#!/usr/bin/env ruby 

t1 = Thread.new { 
puts "Hello_1" 
sleep(5) 
puts "Hello_1 after 5 seconds of sleep" 
} 

t2 = Thread.new { 
puts "Hello_2" 
sleep(5) 
puts "Hello_2 after 5 seconds of sleep" 
} 

t1.join 
t2.join 

puts "Hello_3" 
sleep(5) 
puts "Hello_3 after 5 seconds of sleep" 

第一Hello_1/Hello_2立即執行。在線程成功完成之前,我不希望任何輸出顯示。

回答

6

因爲將打印輸出到單個輸出流(sysout),所以如果要捕獲每個線程的輸出,則不能使用它。

您必須爲每個線程使用單獨的緩衝流,寫入每個線程中的流,然後在線程終止以查看輸出時將其轉儲到sysout。

這裏是一個線程的一個例子:

t = Thread.new() do 
    io = StringIO.new 
    io << "mary" 
    io.puts "fred" 
    io.puts "fred" 
    puts io.string 
end 

你將不得不通過IO線程中的每一個方法。

或看看this創建一個模塊,重定向線程的標準輸出。

但在每個線程,你開始包裝你的代碼:

Thread.start do 
    # capture the STDOUT by storing a StringIO in the thread space 
    Thread.current[:stdout] = StringIO.new 
    # Do your stuff.. print using puts 
    puts 'redirected to StringIO' 
    # print everything before we exit 
    STDIO.puts Thread.current[:stdout].string 
end.join 
+0

你能提供一個簡單的例子?我在其他地方找不到這方面的任何信息。 – awojo 2012-08-01 00:34:25

+0

完美!這很好。 – awojo 2012-08-01 02:23:18

+1

鏈接的博文不​​再可用。你還有代碼嗎?你能否把它變成一個要點並更新答案? – Schneems 2014-02-05 18:02:59

0

您可以共享一個緩衝區,但你應該「同步」訪問它:

buffer = "" 
lock = Mutex.new 

t1 = Thread.new { 
lock.synchronize{buffer << "Hello_1\n"} 
sleep(5) 
lock.synchronize{buffer << "Hello_1 after 5 seconds of sleep\n"} 
} 

t2 = Thread.new { 
lock.synchronize{buffer << "Hello_2\n"} 
sleep(5) 
lock.synchronize{buffer << "Hello_2 after 5 seconds of sleep\n"} 
} 

t1.join 
t2.join 

puts buffer 
+0

謝謝!我更喜歡grillp的例子,因爲我沒有分享任何緩衝區。儘管如此,謝謝。 – awojo 2012-08-01 02:22:59