Why am I getting deadlocks? Using Thread, Queue, and ActiveRecord. Ruby 1.9.3, Rails 2.3.18

£可爱£侵袭症+ 提交于 2019-12-11 09:46:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!