Ruby Language
Draad
Zoeken…
Basic Thread Semantics
Een nieuwe thread los van de uitvoering van de Thread.new
kan worden gemaakt met Thread.new
.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Hiermee wordt de uitvoering van de nieuwe thread automatisch gestart.
Gebruik join
om de uitvoering van de hoofdthread te bevriezen totdat de nieuwe thread stopt:
thr.join #=> ... "Whats the big deal"
Merk op dat de draad mogelijk al is beëindigd wanneer u join aanroept, in welk geval de uitvoering normaal zal doorgaan. Als een subthread nooit wordt samengevoegd en de hoofdthread is voltooid, voert de subthread geen resterende code uit.
Toegang tot gedeelde bronnen
Gebruik een mutex om de toegang te synchroniseren tot een variabele die toegankelijk is via meerdere 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
Anders kan de waarde van de counter
momenteel zichtbaar is voor de ene thread worden gewijzigd door een andere thread.
Voorbeeld zonder Mutex
(zie bijv. Thread 0
, waar Before
and After
meer dan 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
Voorbeeld met 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
Hoe een draad te doden
U roept gebruik Thread.kill
of Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Een thread beëindigen
Een thread wordt beëindigd als het einde van het codeblok is bereikt. De beste manier om een thread vroegtijdig te beëindigen, is om hem te overtuigen het einde van zijn codeblok te bereiken. Op deze manier kan de thread opschoningscode uitvoeren voordat deze sterft.
Deze thread voert een lus uit terwijl de instantievariabele doorgaan waar is. Stel deze variabele in op onwaar, en de draad zal een natuurlijke dood sterven:
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