【问题标题】:Ruby execution order in multithreaded program多线程程序中的Ruby执行顺序
【发布时间】:2017-09-09 22:37:39
【问题描述】:

在为飓风厄玛做准备时,我写了一个快速垃圾脚本来从 exercism.io 下载一堆练习。它可以工作,但是在调用threads.each 时出现我不理解的错误,如果我理解正确,直到threads.each 的所有代码都是同步的,所以我不确定修复的最佳方法是什么。 :

rb:14:in '<main>': undefined method 'each' for nil:NilClass (NoMethodError)

这对我来说很有趣,因为我收到了错误,但程序仍然按预期运行,所以我确定我写得不对。

language = ARGV[0]

exercises = `exercism list #{@language}`.split("\n")

threads = exercises.map do |exercise|
  break if exercise == ''

  Thread.new do
    system("exercism fetch #{language} #{exercise}")
  end
end

threads.each(&:join)

【问题讨论】:

    标签: ruby multithreading


    【解决方案1】:

    使用next 代替break 以便在任何练习为空白时仍设置threadsbreak 将取消整个循环,但next 将仅跳过当前迭代。

    如果他们的练习是空白的,那么一些线程可能仍然是nil,因为没有为他们启动线程。您可以使用threads.compact.each(&:join) 跳过这些nil 值。

    或者如果您需要break,则在循环中添加threads,例如:

    threads = []
    exercises.each do |exercise|
      break if exercise == ''
    
      threads << Thread.new do
        system("exercism fetch #{language} #{exercise}")
      end
    end
    

    【讨论】:

    • 在这种特殊情况下,我知道一旦我们点击"",就没有更多的练习,只是之后的说明。
    • @NoobException break 将阻止对threads 的分配发生,因此您需要将其替换为next,或者摆脱分配,并附加到其中的线程而是循环。
    • 但是您关于在循环中追加的评论确实有道理,如果您回答我会将其标记为正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多