Thread.join阻塞主线程

Ber*_*ard 16 ruby multithreading

调用Thread.join会阻塞当前(主)线程.但是,当主线程退出时,不会调用join会导致所有生成的线程被杀死.如何在不阻塞主线程的情况下在Ruby中生成持久子线程?

这是加入的典型用法.

for i in 1..100 do
  puts "Creating thread #{i}"
  t = Thread.new(i) do |j|
    sleep 1
    puts "Thread #{j} done"
  end
  t.join
end
puts "#{Thread.list.size} threads"
Run Code Online (Sandbox Code Playgroud)

这给了

     Creating thread 1  
     Thread 1 done  
     Creating thread 2  
     Thread 2 done  
     ...  
     1 threads  

但我正在寻找如何得到这个

    Creating thread 1  
    Creating thread 2  
    ...  
    101 threads  
    Thread 1 done  
    Thread 2 done  
    ...  

代码在Ruby 1.8.7和1.9.2中提供相同的输出

Mar*_*off 19

你只需将线程累积在另一个容器中,然后join在它们全部创建之后逐个累积:

my_threads = []
for i in 1..100 do
    puts "Creating thread #{i}"
    my_threads << Thread.new(i) do |j|
        sleep 1
        puts "Thread #{j} done"
    end
end
puts "#{Thread.list.size} threads"

my_threads.each do |t|
    t.join
end
Run Code Online (Sandbox Code Playgroud)

你也不能将线程绑定到i变量,因为i不断被覆盖,你的输出将是100行"Thread 100 done"; 相反,你必须将它绑定到i我巧妙命名的副本j.

  • 在Ruby 1.9中,块参数始终是本地的,因此您无需重命名变量.但是你会收到警告.(*变量`i`阴影外变量*或类似的东西.) (5认同)

joa*_*ast 7

您需要加入循环外部的线程.

for i in 1..100 do
  puts "Creating thread #{i}"
  t = Thread.new(i) do |mi|
    sleep 1
    puts "Thread #{mi} done"
  end
end

# Wait for all threads to end
Thread.list.each do |t|
  # Wait for the thread to finish if it isn't this thread (i.e. the main thread).
  t.join if t != Thread.current
 end
Run Code Online (Sandbox Code Playgroud)