matrices - imprimir matriz ruby
ruby trabajando en elementos de matriz en grupos de cuatro (4)
Si leí correctamente, no desea procesar más de 4 hilos a la vez.
Me parece que deberías lanzar solo 4 subprocesos y hacer que todos los lean desde una cola compartida (parte de la lib del hilo estándar) para procesar los elementos.
Puede hacer que los hilos terminen cuando la cola está vacía.
Cortar la matriz en 4 matrices iguales y hacer que cada hilo procese 1/4 de los elementos asume que cada elemento procesa al mismo tiempo. Si algunos tardan más que otros, algunos de sus hilos terminarán temprano.
Usando una cola, ningún hilo se detiene hasta que la cola compartida esté vacía, por lo que creo que es una solución más eficiente.
Aquí hay un programa de trabajo basado en su código para demostrar:
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 }
Tengo una matriz de script de ruby cuando cada elemento necesita procesamiento:
threads = []
elemets.each do |element|
threads.push(Thread.new{process(element)}}
end
threads.each { |aThread| aThread.join }
sin embargo, debido a limitaciones de recursos, la secuencia de comandos funciona de manera óptima si no se procesan más los cuatro elementos a la vez.
No, sé que puedo volcar cada ciclo y usar una variable para contar 4 elementos y luego esperar, ¿pero hay una manera más fría de hacerlo?
No estoy seguro si la siguiente variante cuenta solo como usar una "variable para contar 4 elementos", o podría considerarse genial, pero le da una matriz en porciones de tamaño no mayor a 4 elementos:
x = (1..10).to_a
0.step(x.size - 1, 4) do |i|
# Choose one
p x.slice(i, 4)
p x[i, 4]
end
Puedes enumerar en grupos de 4 para una matriz:
>> [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]
Entonces puedes probar algo como
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
Aunque puede que no sea lo que necesitas, he estado levantado desde las 3 AM y solo dormí un par de horas. : /
Sí, pero debes hacer algún método anulando. El enfoque habitual es anular ''/'' para Array
así:
class Array
def / len
a = []
each_with_index do |x,i|
a << [] if i % len == 0
a.last << x
end
a
end
end
Y con eso definido, ahora puedes hacer fácilmente:
foo = [1,2,3,4,5,6]
foo / 2
# Result is [[1,2], [3,4], [5,6]]