【问题标题】:How to fix a deadlock caused by open如何修复由 open 引起的死锁
【发布时间】:2016-10-19 09:06:39
【问题描述】:

我有一个死锁,但我没有在我的程序中使用任何线程。此外,该错误大约每 1000 到 1500 次函数调用发生一次,因此很难准确定位和纠正。

这是发生问题时的完整错误消息:

/usr/lib/ruby/2.3.0/timeout.rb:95:in `join': No live threads left. Deadlock? (fatal)
    from /usr/lib/ruby/2.3.0/timeout.rb:95:in `ensure in block in timeout'
    from /usr/lib/ruby/2.3.0/timeout.rb:95:in `block in timeout'
    from /usr/lib/ruby/2.3.0/timeout.rb:101:in `timeout'
    from /usr/lib/ruby/2.3.0/net/http.rb:878:in `connect'
    from /usr/lib/ruby/2.3.0/net/http.rb:863:in `do_start'
    from /usr/lib/ruby/2.3.0/net/http.rb:852:in `start'
    from /usr/lib/ruby/2.3.0/open-uri.rb:319:in `open_http'
    from /usr/lib/ruby/2.3.0/open-uri.rb:737:in `buffer_open'
    from /usr/lib/ruby/2.3.0/open-uri.rb:212:in `block in open_loop'
    from /usr/lib/ruby/2.3.0/open-uri.rb:210:in `catch'
    from /usr/lib/ruby/2.3.0/open-uri.rb:210:in `open_loop'
    from /usr/lib/ruby/2.3.0/open-uri.rb:151:in `open_uri'
    from /usr/lib/ruby/2.3.0/open-uri.rb:717:in `open'
    from /usr/lib/ruby/2.3.0/open-uri.rb:35:in `open'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/utils.rb:85:in `get_pic'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:87:in `page_link'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:116:in `chapter_link'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:142:in `chapter'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:57:in `block in MF_manga_missing_chapters'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:45:in `reverse_each'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:45:in `MF_manga_missing_chapters'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:80:in `MF_update'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:5:in `update_manga'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:15:in `block in update_all'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:14:in `each'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:14:in `update_all'
    from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:22:in `update'
    from ./MangaScrap.rb:28:in `<main>'

完整程序的链接是https://github.com/Hellfire01/MangaScrap

问题发生在使用open 的三种不同方法上。这是这次崩溃的那个:

# conect to link and download picture
def get_pic(link)
  safe_link = link.gsub(/[\[\]]/) { '%%%s' % $&.ord.to_s(16) }
  tries ||= 20
  begin
    page = open(safe_link, "User-Agent" => "Ruby/#{RUBY_VERSION}")
  rescue URI::InvalidURIError => error
    puts "Warning : bad url"
    puts link
    puts "message is : " + error.message
    return nil
  rescue => error
    if tries > 0
    tries -= 1
    sleep(0.2)
    retry
    else
      puts 'could not get picture ' + safe_link + ' after ' + $nb_tries.to_s + ' tries'
      puts "message is : " + error.message
      return nil
    end
  end
  sleep(0.2)
  return page
end

这是文件的链接:https://github.com/Hellfire01/MangaScrap/blob/master/sources/utils.rb

我想知道:

  • 如何解决此错误?
  • 如果我无法修复此错误,是否可以使用 OpenUri 的替代品?

【问题讨论】:

  • 仅供参考,尽管没有使用线程,但出现线程错误的原因是 net/http 正在使用 ruby​​ 超时库(而 open-uri 又使用了),而超时使用了线程
  • 是的,我猜了这么多,但我仍然不知道如何解决这个问题:/
  • curb 比原始的 Net::HTTP 更愉快。
  • 感谢您的提示,我会调查的^^

标签: ruby timeout deadlock open-uri


【解决方案1】:

您没有在这里捕获所有异常。如果在rescue 之后没有指定任何内容,则表示您正在捕获不在异常层次结构根部的StandardError

如果您想确保捕获所有异常并重试打开 URL(或任何您想要的行为),您想要做的是:

rescue Exception => error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2018-07-28
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多