Comment puis-je gérer ruby fils de sorte qu'ils finissent leur travail?
J'ai un calcul qui peut être divisé en unités indépendantes et la façon dont je m'occupe maintenant, c'est par la création d'un nombre fixe de threads et ensuite de passer au large de morceaux de travail à faire dans chaque thread. Donc, en pseudo-code, voici à quoi il ressemble
# main thread
work_units.take(10).each {|work_unit| spawn_thread_for work_unit}
def spawn_thread_for(work)
Thread.new do
do_some work
more_work = work_units.pop
spawn_thread_for more_work unless more_work.nil?
end
end
Fondamentalement, une fois le nombre de threads est créé chacun fait un peu de travail et de garde, puis de prendre des trucs à faire à partir de la pile de travail jusqu'à ce qu'il ne reste rien. Tout fonctionne bien quand je lance des choses dans la cisr, mais quand j'execute le script à l'aide de l'interprète les choses ne fonctionnent pas si bien. Je ne suis pas sûr de savoir comment faire le thread principal attendez jusqu'à ce que le travail est terminé. Est-il une bonne façon de le faire ou suis-je coincé avec l'exécution de sleep 10 until work_units.empty?
dans le thread principal
- Ne pas
take(10)
dire que seuls les 10 premierswork_units
seront traitées, jamais? - Grimm: en Fait non, mais en relisant la question, il ressemble à
work_units
serait hors de portée pourspawn_thread_for
pour la lignemore_work = work_units.pop
- Dans le code actuel, c'est une variable d'instance, donc il n'y a pas de délimitation de l'étendue des problèmes.
Vous devez vous connecter pour publier un commentaire.
Si vous modifiez
spawn_thread_for
pour enregistrer une référence à votreThread
, alors vous pouvez appelerThread#join
sur le fil pour attendre l'achèvement:produit:
(Vol à partir de la
ri Thread.new
de la documentation. Voir lari Thread.join
la documentation pour plus de détails.)Donc, si vous modifier
spawn_thread_for
de sauver le Fil références, vous pouvez vous joindre à eux tous:(Non testé, mais devrait donner de la saveur)
threads
assez grand parce que quand un thread se termine, il est la référence est toujours dans lethreads
tableau. En outrethreads
est en train d'être modifiée en cours dethreads.each(&:join)
est en cours d'exécution si ce n'est toujours pas à résoudre le problème.spawn_thread_for
dans chaque thread, il suffit de regarder pour plus de travail et de commencer directement?Queue
classe pour un thread-safe file d'attente de mise en œuvre.)Thread::exit()
plutôt quebreak
?En ruby 1.9 (et 2.0), vous pouvez utiliser
ThreadsWait
de la stdlib à cet effet:ThreadsWait.all_waits(*threads)
etthreads.each { |thr| thr.join }
?Il semble que vous répliquez que le Parallèle (Peach) bibliothèque.
Vous pouvez utiliser Thread#join
join(p1 = v1) public
Vous pouvez également utiliser Énumérable#each_slice pour itérer sur les unités de travail dans les lots