红宝石的平行性

时间:2012-04-19 08:58:18

标签: ruby multithreading

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

每个循环迭代都独立于其他循环,所以我想对它进行分析。

我该怎么做?

我试过了:

myarray.each{|item|
    Thread.start {

        # do stuff

     }
}
puts "foo"

但红宝石似乎马上退出(打印“foo”)。也就是说,它在循环上运行,开始加载线程,但因为each之后没有任何东西,ruby退出杀死其他线程:(

我知道我可以做thread.join,但如果我在循环中这样做,那么它就不再平行了。

我错过了什么?

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

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

由于

3 个答案:

答案 0 :(得分:6)

将所有线程存储在一个数组中并循环遍历调用join的数组:

threads = myarray.map do |item|
  Thread.start do
    # do stuff
  end
end
threads.each { |thread| thread.join }
puts "foo"

答案 1 :(得分: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

答案 2 :(得分:1)

考虑到ruby线程是绿色线程,所以你没有本机真正的并行性。我想这就是你想要的,我建议你去看看JRuby和Rubinius:

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