2017-10-19 3 views
0

L'exécution de cetteComment gardez-vous un fil rubis vivant

# in initialize 
@queue = Queue.new 

@threads = Array.new(NUM_THREADS) do 
    Thread.new do 
     until @queue.empty? 
     puts @queue.shift 
     end 
    end 
    end 

# later in another method, calling 
@threads.each { |t| puts t.alive? } # puts false 
@queue.push('something else') 
# new item is not processed by thread 

Comment puis-je garder un Ruby enfilez vivant afin qu'il puisse continuer d'accepter des choses à partir d'une file d'attente?

Répondre

0

Le problème est que vous initialisez les threads avant d'ajouter quoi que ce soit à la file d'attente. Les threads démarrent et meurent avant l'exécution de la ligne @queue.push.

Si vous voulez rester en vie le fil, même s'il n'y a rien dans la file d'attente, vous pouvez changer la logique du fil il boucles pour toujours:

Thread.new do 
    loop do 
    if val = @queue.shift 
     puts val 
    end 
    end 
end 

Vous pouvez réduire la consommation du processeur en mettant un sleep appel à l'intérieur de la boucle du thread, disons qu'il dort 0,1 seconde à chaque itération et donc il pourrait traiter un maximum de 10 éléments par seconde. Par exemple en cours d'exécution ce qui suit dans mon Ruby REPL soulève le processus consommation CPU d'environ 0 à 25% (ce qui est trop élevée)

100.times { Thread.new { loop { } } } 

Mais ce qui suit utilise moins de 1%:

100.times { Thread.new { loop { sleep 0.1 } } } 

Il existe d'autres moyens de gérer la consommation du processeur des processus d'arrière-plan, à l'exception de l'insertion de numéros sleep arbitraires: par exemple eventmachine, resque ou sidekiq.