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
精彩评论