3

我已经开始研究 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 立即执行。在线程成功完成之前,我不希望显示任何输出。

4

2 回答 2

6

因为将打印输出到单个输出流 (sysout),所以如果要捕获每个线程的输出,则不能使用它。

您必须为每个线程使用单独的缓冲流,在每个线程中写入,然后在线程终止时将它们转储到 sysout 以查看输出。

下面是一个线程示例:

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

您必须将 io 传递给线程中的每个方法。

或者看看这个创建一个为线程重定向标准输出的模块。

但是在您开始包装代码的每个线程中:

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
于 2012-08-01T00:24:57.587 回答
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
于 2012-08-01T01:21:24.047 回答