Ruby: Wait for all threads completed using join and ThreadsWait.all_waits - what the difference?

前端 未结 1 1295
南笙
南笙 2021-01-18 09:14

Consider the following example:

threads = []

(0..10).each do |_|
  threads << Thread.new do
    # do async staff there
    sleep Random.rand(10)
  end         


        
相关标签:
1条回答
  • 2021-01-18 09:52

    The documentation clearly states that all_waits will execute any passed block after each thread's execution; join doesn't offer anything like this.

    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.
    

    To accomplish the same with join, I imagine you would have to do this:

    threads.each do |t|
      t.join
      puts "#{t} complete."
    end # will return threads
    

    Apart from this, the all_waits methods eventually calls the join_nowait method which processes each thread by calling join on it.

    Without any block, I would imagine that directly using join would be faster since you would cut back on all ThreadsWait methods leading up to it. So I gave it a shot:

    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 )
    
    0 讨论(0)
提交回复
热议问题