ruby数组元素在四个组中的工作

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

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

由于资源的限制,如果不再处理四个元素,脚本将以最佳方式工作。

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

您可以枚举数组为4:

 >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].each_slice(4) {|a| pa} [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 

它可能不是你所需要的,但是从凌晨3点起,我只有睡了几个小时。 :/

如果我读了你的话,你一次只想处理4个线程。

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

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

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

使用一个队列,线程停止,直到共享队列是空的,所以这是一个更有效的解决scheme。

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

 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 } 

是的,但是你需要做一些重写的​​方法。 通常的做法是覆盖“/”像这样的Array

 class Array def / len a = [] each_with_index do |x,i| a << [] if i % len == 0 a.last << x end a end end 

而且用这个定义你现在可以轻松地做到:

 foo = [1,2,3,4,5,6] foo / 2 # Result is [[1,2], [3,4], [5,6]] 

不知道是否下面的变种算作只是使用“variables来计数4个元素”,或者可以被认为是很酷,但它给你一个大小不超过4个元素的切片数组:

 x = (1..10).to_a 0.step(x.size - 1, 4) do |i| # Choose one p x.slice(i, 4) px[i, 4] end