开发者

Thread.join blocks the main thread

Calling Thread.join blocks the current (main) thread. However not calling join results in all spawned threads to be killed when the main thread exits. How does one spawn persistent children threads in Ruby without blocking the main thread?

Here's a typical use of join.

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"

This gives

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

but I'm looking for how to get this

    Creating thread 1  
    Creating thread 2  
    ...  
    101 threads  
    Thread 1 done  
    Th开发者_JS百科read 2 done  
    ...  

The code gives the same output in both Ruby 1.8.7 and 1.9.2


You simply accumulate the threads in another container, then join them one-by-one after they've all been created:

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

You also can't bind the thread to the i variable because i gets constantly overwritten, and your output will be 100 lines of "Thread 100 done"; instead, you have to bind it to a copy of i, which I have cleverly named j.


You need to join the threads outside of the loop.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜