gpt4 book ai didi

ruby - 如何跟踪 Ruby 中的死锁

转载 作者:数据小太阳 更新时间:2023-10-29 06:46:47 26 4
gpt4 key购买 nike

我使用 BrB为我用 Process#fork fork 的 Ruby 1.9 中的各种工作进程共享数据源:

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

worker fork 如下:

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 <main>'
from bootstrap.rb:39:in `fork'
from bootstrap.rb:39:in `<main>'</pre>

这个错误并没有告诉我很多关于死锁实际发生的地方,它只是指向 EventMachine 线程上的 join

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

最佳答案

它在父线程中锁定 join,该信息是准确的。要跟踪它在子线程中的锁定位置,请尝试将线程的工作包装在 timeout block 中。 .您需要暂时移除包罗万象的 rescue 以引发超时异常。

目前父线程尝试按顺序加入所有线程,阻塞直到每个线程完成。但是,每个线程只会在 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

关于ruby - 如何跟踪 Ruby 中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3153224/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com