Pat*_*ien 10 ruby multithreading deadlock locking backtrace
我使用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
Run Code Online (Sandbox Code Playgroud)
工人分叉如下:
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
Run Code Online (Sandbox Code Playgroud)
这非常完美,但运行大约10分钟后,我收到以下错误:
bootstrap.rb:47:in `join': deadlock detected (fatal)
from bootstrap.rb:47:in `block in <main>'
from bootstrap.rb:39:in `fork'
from bootstrap.rb:39:in `<main>'</pre>
Run Code Online (Sandbox Code Playgroud)
现在这个错误并没有告诉我有关死锁实际发生的位置,它只指向了EventMachine线程上的连接.
如何追溯程序锁定的位置?
它锁定了父线程中的连接,该信息是准确的. 要跟踪它在子线程中锁定的位置,请尝试将线程的工作包装在超时块中.您需要临时删除全部抢救以获取超时异常.
目前,父线程尝试按顺序连接所有线程,阻塞直到每个线程完成.但是每个线程只会加入OutOfTargetsError.可以通过使用短期线程并将while循环移动到父级来避免死锁.没有保证,但也许是这样的?
8.times do |t|
fork do
running = true
Signal.trap("INT") do
puts "Interrupt signal received, waiting for threads to finish..."
running = false
end
data = BrB::Tunnel.create(nil, "brb://#{host}:#{port}", :verbose => false)
puts "Launching max #{threads_num} worker threads... (PID: #{Process.pid})"
threads = []
while running
# Start new threads until we have threads_num running
until threads.length >= threads_num do
threads << Thread.new {
begin
worker = Worker.new(data, config)
rescue OutOfTargetsError
rescue Exception => e
puts "An unexpected exception was caught: #{e.class} => #{e}"
sleep 5
end
}
end
# Make sure the parent process doesn't spin too much
sleep 1
# Join finished threads
finished_threads = threads.reject &:status
threads -= finished_threads
finished_threads.each &:join
end
data.stop_service
EM.stop
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2967 次 |
| 最近记录: |