rbuy travaillant sur des éléments de tableau en groupes de quatre

J’ai un tableau de script ruby ​​lorsque chaque élément a besoin d’être traité:

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

En raison des limitations de ressources, le script fonctionne de manière optimale si les quatre éléments ne sont plus traités simultanément.

non, je sais que je peux vider chaque boucle et utiliser une variable pour compter 4 éléments, puis attendre, mais y a-t-il un moyen plus cool de le faire?

Vous pouvez énumérer des groupes de 4 pour un tableau:

 >> [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] 

Donc, vous pouvez essayer quelque chose comme

 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 

Ce n’est peut-être pas ce dont vous avez besoin, mais je suis debout depuis 3 heures du matin et je n’ai dormi que quelques heures. : /

Si je vous lis bien, vous ne voulez pas avoir plus de 4 processus de traitement à la fois.

Il me semble que vous ne devriez lancer que 4 threads, et les faire tous lire depuis une queue partagée (qui fait partie de la lib thread standard) pour traiter les éléments.

Vous pouvez faire en sorte que les threads se terminent lorsque la queue est vide.

Le découpage du tableau en 4 tableaux égaux, et chaque processus de processus 1/4 des éléments suppose que chaque élément est traité simultanément. Si certains prennent plus de temps que d’autres, certains de vos fils se termineront tôt.

En utilisant une queue, aucun thread ne s’arrête tant que la queue partagée n’est pas vide. Je pense donc que la solution est plus efficace.

Voici un programme de travail basé sur votre code pour montrer:

 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 } 

Vous ne savez pas si la variante suivante ne compte que pour utiliser une “variable pour compter 4 éléments”, ou pourrait être considérée comme cool, mais vous obtenez un tableau en tranches de taille inférieure à 4 éléments:

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

Oui, mais vous devez effectuer certaines méthodes. L’approche habituelle consiste à remplacer ‘/’ pour Array comme ceci:

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

Et avec cela défini, vous pouvez maintenant facilement faire:

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