Ruby Language
Hilo
Buscar..
Semántica de hilo básico
Se puede crear un nuevo hilo separado de la ejecución del hilo principal, usando Thread.new
.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Esto iniciará automáticamente la ejecución del nuevo hilo.
Para congelar la ejecución del hilo principal, hasta que el nuevo hilo se detenga, use join
:
thr.join #=> ... "Whats the big deal"
Tenga en cuenta que el subproceso ya puede haber finalizado cuando llama a unirse, en cuyo caso la ejecución continuará normalmente. Si un subproceso nunca se une y el subproceso principal se completa, el subproceso no ejecutará ningún código restante.
Acceso a recursos compartidos
Use un mutex para sincronizar el acceso a una variable a la que se accede desde varios subprocesos:
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
De lo contrario, el valor del counter
actualmente visible para un hilo podría ser cambiado por otro hilo.
Ejemplo sin Mutex
(ver, por ejemplo, el Thread 0
, donde Before
y After
difieren en más 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
Ejemplo con 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
Cómo matar un hilo
Usted llama usar Thread.kill
o Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Terminando un hilo
Un hilo termina si llega al final de su bloque de código. La mejor manera de terminar un hilo temprano es convencerlo de que llegue al final de su bloque de código. De esta manera, el hilo puede ejecutar código de limpieza antes de morir.
Este hilo ejecuta un bucle mientras que la variable de instancia continue es verdadera. Establece esta variable en falso, y el hilo morirá una muerte natural:
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