Ruby Language
Filo
Ricerca…
Semantica del thread di base
Un nuovo thread separato dall'esecuzione del thread principale può essere creato utilizzando Thread.new
.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Questo avvierà automaticamente l'esecuzione del nuovo thread.
Per bloccare l'esecuzione del thread principale, fino a quando il nuovo thread si arresta, usa join
:
thr.join #=> ... "Whats the big deal"
Si noti che il thread potrebbe aver già finito quando si chiama join, nel qual caso l'esecuzione continuerà normalmente. Se un sottoprocesso non viene mai unito e il thread principale viene completato, il sottoprocesso non eseguirà alcun codice rimanente.
Accesso alle risorse condivise
Utilizzare un mutex per sincronizzare l'accesso a una variabile a cui si accede da più thread:
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
In caso contrario, il valore del counter
attualmente visibile su un thread potrebbe essere modificato da un altro thread.
Esempio senza Mutex
(vedi ad esempio Thread 0
, dove Before
e After
differiscono di più di 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
Esempio 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
Come uccidere un thread
Thread.kill
usa Thread.kill
o Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Terminare una discussione
Un thread termina se raggiunge la fine del suo blocco di codice. Il modo migliore per terminare anticipatamente un thread è convincerlo a raggiungere la fine del suo blocco di codice. In questo modo, il thread può eseguire il codice di pulizia prima di morire.
Questo thread esegue un ciclo mentre la variabile di istanza continua è true. Imposta questa variabile su false e il thread morirà di morte naturale:
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