2

我的 ruby​​ 构建脚本中有一个循环,它遍历每个项目并调用 msbuild 并执行各种其他操作,例如缩小 css/js。

每个循环迭代都独立于其他循环迭代,所以我想并行化它。

我该怎么做呢?

我试过了:

myarray.each{|item|
    Thread.start {

        # do stuff

     }
}
puts "foo"

但 ruby​​ 似乎立即退出(打印“foo”)。也就是说,它在循环上运行,启动了一个线程负载,但是因为在 之后没有任何东西each,ruby 退出杀死其他线程:(

我知道我可以做到thread.join,但如果我在循环内这样做,那么它不再是并行的。

我错过了什么?

我知道http://peach.rubyforge.org/但是使用它我会得到各种奇怪的行为,这些行为看起来像我不知道如何解决的变量范围问题:(

编辑:如果我可以在放置“foo”之前等待所有子线程执行,或者至少是主 ruby​​ 线程退出,那将很有用。这可能吗?

谢谢

4

3 回答 3

6

将所有线程存储在一个数组中,并通过数组调用 join 循环:

threads = myarray.map do |item|
  Thread.start do
    # do stuff
  end
end
threads.each { |thread| thread.join }
puts "foo"
于 2012-04-19T09:10:38.597 回答
2

在这里使用em-synchrony :)。纤维很可爱。

require "em-synchrony"
require "em-synchrony/fiber_iterator"

# if you realy need to get a Fiber per each item
# in real life you could set concurrency to, for example, 10 and it could even improve performance
# it depends on amount of IO in your job
concurrency = myarray.size
EM.synchrony do
  EM::Synchrony::FiberIterator.new(myarray, concurrency).each do |url|
    # do some job here
  end
  EM.stop
end
于 2012-04-19T09:15:52.773 回答
1

考虑到 ruby​​ 线程是绿色线程,所以你没有原生的真正并行性。如果这是你想要的,我建议你看看 JRuby 和 Rubinius:

http://www.engineyard.com/blog/2011/concurrency-in-jruby/

于 2012-04-19T09:03:59.543 回答