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?
调用Thread.join会阻塞当前(主)线程。但是,当主线程退出时,不会调用join会导致所有生成的线程被杀死。如何在不阻塞主线程的情况下在Ruby中生成持久子线程?
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
代码在Ruby 1.8.7和1.9.2中提供相同的输出
2 个解决方案
#1
18
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
.
你也无法将线程绑定到i变量,因为我不断被覆盖,你的输出将是100行“Thread 100 done”;相反,你必须将它绑定到i的副本,我巧妙地将其命名为j。
#2
6
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
#1
18
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
.
你也无法将线程绑定到i变量,因为我不断被覆盖,你的输出将是100行“Thread 100 done”;相反,你必须将它绑定到i的副本,我巧妙地将其命名为j。
#2
6
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