问题
I mitigate the low success rate of a particular operation by running multiple threads and waiting for the first one to return with a valid answer. I've created a minimal example below:
THREADS = [] if !defined?(THREADS)
def threadtest
THREADS.clear
queue, mutex, result = Queue.new, Mutex.new, nil
10.times do |i|
THREADS << Thread.new do
counted = (10e6 + rand(10e6)).to_i.times { } # randomize computation time
num = rand(8) # succeed only 1/8 of the time
#mutex.synchronize do # even if wrapped in mutex
# print "#{User.last.inspect}\n" # deadlocks below if uncommented
#end
queue << [num, counted, i]
end
end
10.times do |i|
result, counted, num = queue.pop # deadlocks here
if result.zero?
puts "#{i}: #{num} succeeds after #{counted} counts"
break
elsif num.present?
puts "#{i}: #{num} failed with #{result} after #{counted} counts"
end
end
THREADS.each(&:exit)
return result
end
30.times { threadtest } # deadlock happens on "high load"
The error looks like:
fatal: deadlock detected
from /usr/lib/ruby/1.9.1/thread.rb:189:in `sleep'
from /usr/lib/ruby/1.9.1/thread.rb:189:in `block in pop'
from <internal:prelude>:10:in `synchronize'
from /usr/lib/ruby/1.9.1/thread.rb:184:in `pop'
from (irb):38:in `block in threadtest'
from (irb):37:in `times'
from (irb):37:in `threadtest'
from (irb):53:in `block in irb_binding'
from (irb):53:in `times'
from (irb):53
from /usr/local/bin/irb:12:in `<main>'
I've tried many variations in an attempt to prevent the deadlock, all to no avail. I can detail some of the experimentations I've done so far if requested. I do have one more idea that I've been avoiding due to the amount of refactoring it'd require in my application.
Is it simply the case that ActiveRecord can't be accessed via multiple threads?
I'll update with a few more details as I think of them.
'deadlock detected' error in rails is the the closest related question I found, but it's got no answers.
回答1:
I had the same error and had to add the
gem 'net-ssh-gateway'
in the file Gemfile.lock
, because the version that was bundled didn't work with the installed ruby. Seems like the dependency wasn't resolved any more in the newer ruby version.
来源:https://stackoverflow.com/questions/26001994/why-am-i-getting-deadlocks-using-thread-queue-and-activerecord-ruby-1-9-3-r