6
votes

Filetage en rubis avec une limite

J'ai une tâche que j'ai besoin d'exécuter, do_stuff (opts) , qui prendra ~ 1s chacun, même pendant que 1 à 10 d'entre eux fonctionnent en parallèle. J'ai besoin de collecter un tableau des résultats pour chaque opération à la fin.

Si j'ai 30 trucs à faire, comment utiliserais-i de la filetage efficacement pour faire la queue sur les opérations do_stuff (opts) de sorte que pas plus de 10 fonctionnent simultanément, mais le tableau des résultats n'est pas donné. / Imprimé / etc jusqu'à ce que toutes les tâches (30) ont été terminées?

J'ai généralement au moins un certain code pour essayer d'illustrer ce que je veux dire, mais avec enfilage, je suis un peu une perte! Merci d'avance


0 commentaires

6 Réponses :


3
votes

Vous devez implémenter Ce modèle
Cette question discute de la manière dont cela peut être fait à Ruby


0 commentaires

1
votes

Aussi, jetez un coup d'œil à Ce tutoriel si vous êtes Nouveaux fils rubis.


3 commentaires

Votre lien semble être mort. Y a-t-il une copie quelque part?


@Naremy, j'ai corrigé le lien. S'il vous plaît upvote quand vous avez un moment.


Je n'étais pas le descendant mais si je peux rendre votre heureux;)



1
votes

Si vous êtes vraiment après la performance, vous voudrez peut-être aussi regarder Jruby .
Il utilise des fils d'exploitation réels et non des threads verts Les autres implémentations rubis utilisent


0 commentaires

6
votes

Je ne sais pas à quel point cela fonctionnera pour une application plus complexe, mais j'ai trouvé quelque chose comme ça pour travailler bien pour un scénario de filetage simple avec MacRuby.

thread_limit = 4

threads = []
things_to_process.each do |thing|
  until threads.map { |t| t.status }.count("run") < thread_limit do sleep 5 end
  threads << Thread.new { the_task(thing) }
end
output = threads.map { |t| t.value }


1 commentaires

J'ai eu la chance d'utiliser fil.alive? Au lieu de statut: threads.map {| t | t.alive?}. Comptez (vrai)



1
votes

Cette solution regroupe des résultats dans $ de résultats de résultats. Il permet de créer des threads 'thread_limit' à créer, puis les attend de compléter avant de ne plus créer.

   $results = []

   def do_stuff(opts={})
     'done'
   end

   def thread_wait(threads)
     threads.each{|t| t.join}
     threads.each {|t| $results << t }
     threads.delete_if {|t| t.status == false}
     threads.delete_if {|t| t.status.nil? }
   end

   opts = {}
   thread_limit = 20
   threads = []
   records.each do |r|
     thread_wait(threads) while threads.length >= thread_limit
     t = Thread.new { do_stuff(opts) }
     t.abort_on_exception = true
     threads << t
   end
   # Ensure remaining threads complete
   threads.each{|t| t.join}


0 commentaires

0
votes

J'utilise parals et paralsmap : xxx

par exemple: xxx > Vous pouvez utiliser le paramètre n pour limiter le nombre de threads.


0 commentaires