Как проследить мертвую блокировку в Ruby

Я использую BrB для совместного использования источника данных для различных рабочих процессов в Ruby 1.9, с которым я разветвляюсь Process#fork:

Thread.abort_on_exception = true

fork do
  puts "Initializing data source process... (PID: #{Process.pid})"
  data = DataSource.new(files)

  BrB::Service.start_service(:object => data, :verbose => false, :host => host, :port => port)
  EM.reactor_thread.join
end

Рабочие разветвлены следующим образом:

8.times do |t|  
  fork do
    data = BrB::Tunnel.create(nil, "brb://#{host}:#{port}", :verbose => false)

    puts "Launching #{threads_num} worker threads... (PID: #{Process.pid})"    

    threads = []
    threads_num.times { |i|
      threads << Thread.new {
        while true
          begin
            worker = Worker.new(data, config)

          rescue OutOfTargetsError
            break

          rescue Exception => e
            puts "An unexpected exception was caught: #{e.class} => #{e}"
            sleep 5

          end
        end
      }
    }
    threads.each { |t| t.join }

    data.stop_service
    EM.stop
  end
end

Это работает в значительной степени отлично, но приблизительно после 10 минут выполнения я получаю следующую ошибку:

bootstrap.rb:47:in `join': deadlock detected (fatal)
    from bootstrap.rb:47:in `block in 
' from bootstrap.rb:39:in `fork' from bootstrap.rb:39:in `
'

Эта ошибка не говорит мне очень о том, где мертвая блокировка на самом деле происходит, она только указывает на меня на join на потоке EventMachine.

Как я прослеживаю, в которой точке запирается программа?

10
задан the Tin Man 9 July 2019 в 22:01
поделиться