Ruby Language
Fil
Recherche…
Sémantique de fil de base
Un nouveau thread séparé de l'exécution du thread principal peut être créé à l'aide de Thread.new
.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Cela démarrera automatiquement l'exécution du nouveau thread.
Pour geler l'exécution du thread principal, jusqu'à ce que le nouveau thread s'arrête, utilisez join
:
thr.join #=> ... "Whats the big deal"
Notez que le thread peut déjà être terminé lorsque vous appelez join, auquel cas l'exécution se poursuivra normalement. Si un sous-thread n'est jamais joint et que le thread principal se termine, le sous-thread n'exécutera aucun code restant.
Accéder aux ressources partagées
Utilisez un mutex pour synchroniser l'accès à une variable accessible à partir de plusieurs threads:
counter = 0
counter_mutex = Mutex.new
# Start three parallel threads and increment counter
3.times.map do |index|
Thread.new do
counter_mutex.synchronize { counter += 1 }
end
end.each(&:join) # Wait for all threads to finish before killing the process
Sinon, la valeur du counter
actuellement visible pour un thread peut être modifiée par un autre thread.
Exemple sans Mutex
(voir par exemple Thread 0
, où Before
et After
diffèrent de plus de 1
):
2.2.0 :224 > counter = 0; 3.times.map { |i| Thread.new { puts "[Thread #{i}] Before: #{counter}"; counter += 1; puts "[Thread #{i}] After: #{counter}"; } }.each(&:join)
[Thread 2] Before: 0
[Thread 0] Before: 0
[Thread 0] After: 2
[Thread 1] Before: 0
[Thread 1] After: 3
[Thread 2] After: 1
Exemple avec Mutex
:
2.2.0 :226 > mutex = Mutex.new; counter = 0; 3.times.map { |i| Thread.new { mutex.synchronize { puts "[Thread #{i}] Before: #{counter}"; counter += 1; puts "[Thread #{i}] After: #{counter}"; } } }.each(&:join)
[Thread 2] Before: 0
[Thread 2] After: 1
[Thread 1] Before: 1
[Thread 1] After: 2
[Thread 0] Before: 2
[Thread 0] After: 3
Comment tuer un fil
Vous appelez utiliser Thread.kill
ou Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Terminer un fil
Un thread se termine s'il atteint la fin de son bloc de code. La meilleure façon de terminer un thread tôt est de le convaincre d’atteindre la fin de son bloc de code. De cette façon, le thread peut exécuter du code de nettoyage avant de mourir.
Ce thread exécute une boucle alors que la variable d'instance continue est vraie. Définissez cette variable sur false et le thread mourra d'une mort naturelle:
require 'thread'
class CounterThread < Thread
def initialize
@count = 0
@continue = true
super do
@count += 1 while @continue
puts "I counted up to #{@count} before I was cruelly stopped."
end
end
def stop
@continue = false
end
end
counter = CounterThread.new
sleep 2
counter.stop