跟踪Ruby中的僵局

前端之家收集整理的这篇文章主要介绍了跟踪Ruby中的僵局前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用 BrB在Ruby 1.9中为各种工作进程共享一个数据源,我用Process#fork来分支,如下所示:
  1. Thread.abort_on_exception = true
  2.  
  3. fork do
  4. puts "Initializing data source process... (PID: #{Process.pid})"
  5. data = DataSource.new(files)
  6.  
  7. BrB::Service.start_service(:object => data,:verbose => false,:host => host,:port => port)
  8. EM.reactor_thread.join
  9. end

工人分叉如下:

  1. 8.times do |t|
  2. fork do
  3. data = BrB::Tunnel.create(nil,"brb://#{host}:#{port}",:verbose => false)
  4.  
  5. puts "Launching #{threads_num} worker threads... (PID: #{Process.pid})"
  6.  
  7. threads = []
  8. threads_num.times { |i|
  9. threads << Thread.new {
  10. while true
  11. begin
  12. worker = Worker.new(data,config)
  13.  
  14. rescue OutOfTargetsError
  15. break
  16.  
  17. rescue Exception => e
  18. puts "An unexpected exception was caught: #{e.class} => #{e}"
  19. sleep 5
  20.  
  21. end
  22. end
  23. }
  24. }
  25. threads.each { |t| t.join }
  26.  
  27. data.stop_service
  28. EM.stop
  29. end
  30. end

这样做非常完美,但运行大约10分钟后,我会收到以下错误信息:

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

现在这个错误并没有告诉我关于死锁实际发生的地方,它只是指向我在EventMachine线程上的连接.

如何追溯程序锁定的时间?

解决方法

它锁定在父线程中加入,该信息是准确的.
要跟踪它在子线程中锁定的位置,请尝试将线程的工作包在 timeout block中.您需要临时删除超时异常的catch-all rescue.

目前,父线程尝试按顺序加入所有线程,阻塞直到每个线程完成.但是每个线程只会加入OutOfTargetsError.使用短命的线程并将while循环移动到父节点可能会避免死锁.没有保证,但也许这样的事情?

  1. 8.times do |t|
  2. fork do
  3. running = true
  4. Signal.trap("INT") do
  5. puts "Interrupt signal received,waiting for threads to finish..."
  6. running = false
  7. end
  8.  
  9. data = BrB::Tunnel.create(nil,:verbose => false)
  10.  
  11. puts "Launching max #{threads_num} worker threads... (PID: #{Process.pid})"
  12.  
  13. threads = []
  14. while running
  15. # Start new threads until we have threads_num running
  16. until threads.length >= threads_num do
  17. threads << Thread.new {
  18. begin
  19. worker = Worker.new(data,config)
  20. rescue OutOfTargetsError
  21. rescue Exception => e
  22. puts "An unexpected exception was caught: #{e.class} => #{e}"
  23. sleep 5
  24. end
  25. }
  26. end
  27.  
  28. # Make sure the parent process doesn't spin too much
  29. sleep 1
  30.  
  31. # Join finished threads
  32. finished_threads = threads.reject &:status
  33. threads -= finished_threads
  34. finished_threads.each &:join
  35. end
  36.  
  37. data.stop_service
  38. EM.stop
  39. end
  40. end

猜你在找的Ruby相关文章