ruby怎么以四个一组的方式处理数组元素?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

当每个元素需要处理时,我有一个ruby脚本:

threads = []
elemets.each do  |element|
    threads.push(Thread.new{process(element)}}
end
threads.each { |aThread|  aThread.join }

由于资源限制,如果一次处理量低于四个元素,脚本将以最佳方式工作。

我知道我可以转储每个循环,并使用一个变量来计算4个元素,然后等待,但有没有更好的方式来做到这一点?

提问于
用户回答回答于

你可以:

>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].each_slice(4) {|a| p a}
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]

类似的东西

elements.each_slice(4) do | batch |
    batch.each do | element |
        threads.push(Thread.new{process(element)}}

    end
    (do stuff to check to see if the threads are done, otherwise wait )
end

用户回答回答于

如果我没看错的话,你一次只想处理不超过4个线程。

听起来像你应该启动只有4个线程,并让他们都从共享队列(标准线程库的一部分)读取来处理元素。

当队列为空时,可以让线程结束。

将数组切分成4个相等的数组,并让每个线程处理1/4个元素,假定每个元素都在同一时间处理。如果有些人比别人花更长的时间,你的一些线索会提前结束。

使用队列,在共享队列为空之前不会停止线程,所以我认为这是一个更有效的解决方案。

这里是一个基于你的代码的工作程序来演示:

require 'thread'

elements = [1,2,3,4,5,6,7,8,9,10]

def process(element)
    puts "working on #{element}"
    sleep rand * 10
end

queue = Queue.new
elements.each{|e| queue << e }

threads = []
4.times do
    threads << Thread.new do
      while (e = queue.pop(true) rescue nil)
        process(e)
      end
    end
end

threads.each {|t| t.join }

扫码关注云+社区