Ruby:等待所有线程完成使用 join 和 ThreadsWait.all_waits - 有什么区别?
Ruby: Wait for all threads completed using join and ThreadsWait.all_waits - what the difference?
考虑以下示例:
threads = []
(0..10).each do |_|
threads << Thread.new do
# do async staff there
sleep Random.rand(10)
end
end
完成后有两种等待方式:
使用连接:
threads.each(&:join)
使用ThreadsWait
:
ThreadsWait.all_waits(threads)
这两种方式有什么区别吗?
我知道 ThreadsWait
class 还有其他有用的方法。
并特别询问 all_waits
方法。
documentation 明确指出 all_waits
将在每个线程执行后执行任何传递的块; join
不提供此类服务。
require "thwait"
threads = [Thread.new { 1 }, Thread.new { 2 }]
ThreadsWait.all_waits(threads) do |t|
puts "#{t} complete."
end # will return nil
# output:
# #<Thread:0x00000002773268> complete.
# #<Thread:0x00000002772ea8> complete.
要用 join
完成同样的事情,我想你必须这样做:
threads.each do |t|
t.join
puts "#{t} complete."
end # will return threads
除此之外,all_waits
方法最终会调用 join_nowait
方法,该方法通过调用 join
来处理每个线程。
没有任何块,我想直接使用 join
会更快,因为你会减少所有导致它的 ThreadsWait
方法。所以我试了一下:
require "thwait"
require "benchmark"
loops = 100_000
Benchmark.bm do |x|
x.report do
loops.times do
threads = [Thread.new { 2 * 1000 }, Thread.new { 4 * 2000 }]
threads.each(&:join)
end
end
x.report do
loops.times do
threads = [Thread.new { 2 * 1000 }, Thread.new { 4 * 2000 }]
ThreadsWait.all_waits(threads)
end
end
end
# results:
# user system total real
# 4.030000 5.750000 9.780000 ( 5.929623 )
# 12.810000 17.060000 29.870000 ( 17.807242 )
使用 map 而不是 each,将等待它们,因为它需要它们的值来构建地图。
(0..10).map do |_|
Thread.new do
# do async staff there
sleep Random.rand(10)
end
end.map(&:join).map(&:value)
考虑以下示例:
threads = []
(0..10).each do |_|
threads << Thread.new do
# do async staff there
sleep Random.rand(10)
end
end
完成后有两种等待方式:
使用连接:
threads.each(&:join)
使用
ThreadsWait
:ThreadsWait.all_waits(threads)
这两种方式有什么区别吗?
我知道 ThreadsWait
class 还有其他有用的方法。
并特别询问 all_waits
方法。
documentation 明确指出 all_waits
将在每个线程执行后执行任何传递的块; join
不提供此类服务。
require "thwait"
threads = [Thread.new { 1 }, Thread.new { 2 }]
ThreadsWait.all_waits(threads) do |t|
puts "#{t} complete."
end # will return nil
# output:
# #<Thread:0x00000002773268> complete.
# #<Thread:0x00000002772ea8> complete.
要用 join
完成同样的事情,我想你必须这样做:
threads.each do |t|
t.join
puts "#{t} complete."
end # will return threads
除此之外,all_waits
方法最终会调用 join_nowait
方法,该方法通过调用 join
来处理每个线程。
没有任何块,我想直接使用 join
会更快,因为你会减少所有导致它的 ThreadsWait
方法。所以我试了一下:
require "thwait"
require "benchmark"
loops = 100_000
Benchmark.bm do |x|
x.report do
loops.times do
threads = [Thread.new { 2 * 1000 }, Thread.new { 4 * 2000 }]
threads.each(&:join)
end
end
x.report do
loops.times do
threads = [Thread.new { 2 * 1000 }, Thread.new { 4 * 2000 }]
ThreadsWait.all_waits(threads)
end
end
end
# results:
# user system total real
# 4.030000 5.750000 9.780000 ( 5.929623 )
# 12.810000 17.060000 29.870000 ( 17.807242 )
使用 map 而不是 each,将等待它们,因为它需要它们的值来构建地图。
(0..10).map do |_|
Thread.new do
# do async staff there
sleep Random.rand(10)
end
end.map(&:join).map(&:value)