Techioz Blog

Ruby スレッド プールが ThreadError.queue _empty で一時停止中

概要

サブディレクトリを実行して内容を分析するスクリプトを作成しようとしています。私はスレッドプールを使用していますが、これによりパフォーマンスが大幅に向上しました。ただし、ThreadError -> empty queue エラーにより、スクリプトが完了近くで一時停止しており、プログラムが 1 分近くハングします。エラーを無視してプロセスを続行することはできないようです。現在のコード:

children = Dir.children(MEDIA_FOLDER)

Thread.report_on_exception = false
Thread.abort_on_exception = false

jobs = Queue.new
children.each { |i| jobs.push i }

workers = 8.times.map do
  Thread.new do
    begin
      while (x = jobs.pop(true))
        check_subdirectory(x)
      end
    rescue Exception => error
      # handle error so it doesnt hang
      puts error
    end
  end
end

workers.map(&:join)

助けていただければ幸いです

解決策

ここで例外を発生させる必要はありません。jobs.pop を使用してキューを閉じるだけです (deq は Pop のエイリアスです)。

https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://rubyapi.org/3.3/o/thread/queue#method-i-close

例えば:

jobs = Thread::Queue.new

10.times do |i|
  jobs << i
  puts "#{i} produced"
end

workers = 4.times.map do
  Thread.new do
    while value = jobs.pop
      sleep rand(2)
      puts "consumed #{value}"
    end
  end
end

jobs.close
workers.map(&:join)

# =>
# 0 produced
# 1 produced
# 2 produced
# 3 produced
# 4 produced
# 5 produced
# 6 produced
# 7 produced
# 8 produced
# 9 produced
# consumed 2
# consumed 3
# consumed 4
# consumed 5
# consumed 6
# consumed 8
# consumed 9
# consumed 0
# consumed 1
# consumed 7