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 Thread 2 done ...
The code gives the same output in both Ruby 1.8.7 and 1.9.2
Join is a synchronization method that blocks the calling thread (that is, the thread that calls the method) until the thread whose Join method is called has completed. Use this method to ensure that a thread has been terminated. The caller will block indefinitely if the thread does not terminate.
A Blocked state will occur whenever a thread tries to acquire lock on object and some other thread is already holding the lock. Once other threads have left and its this thread chance, it moves to Runnable state after that it is eligible pick up work based on JVM threading mechanism and moves to run state.
Blocked means execution gets stuck there; generally, the thread is put to sleep by the system and yields the processor to another thread. When a thread is blocked trying to acquire a mutex, execution resumes when the mutex is released, though the thread might block again if another thread grabs the mutex before it can.
Joining a thread means to wait for it to complete. That is, block the current thread until another completes.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With