Ruby Language
Faden
Suche…
Grundlegende Thread-Semantik
Ein neuer Thread unabhängig von der Ausführung des Hauptthreads kann mit Thread.new
erstellt werden.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Dadurch wird automatisch die Ausführung des neuen Threads gestartet.
Um die Ausführung des Haupt-Threads einzufrieren, bis der neue Thread stoppt, verwenden Sie join
:
thr.join #=> ... "Whats the big deal"
Beachten Sie, dass der Thread möglicherweise bereits beendet wurde, wenn Sie join aufrufen. In diesem Fall wird die Ausführung normal fortgesetzt. Wenn ein Sub-Thread nie zusammengefügt wird und der Haupt-Thread abgeschlossen ist, führt der Sub-Thread keinen verbleibenden Code aus.
Zugriff auf gemeinsam genutzte Ressourcen
Verwenden Sie einen Mutex, um den Zugriff auf eine Variable zu synchronisieren, auf die von mehreren Threads aus zugegriffen wird:
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
Andernfalls wird der Wert des counter
könnte momentan sichtbar einen Thread von einem anderen Thread geändert werden.
Beispiel ohne Mutex
(siehe zB Thread 0
, wo Sie Before
und After
mehr als unterscheiden 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
Beispiel mit 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
Wie man einen Thread tötet
Sie rufen use Thread.kill
oder Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Einen Thread beenden
Ein Thread endet, wenn er das Ende seines Codeblocks erreicht. Um einen Thread vorzeitig zu beenden, müssen Sie ihn dazu bringen, das Ende seines Codeblocks zu erreichen. Auf diese Weise kann der Thread Bereinigungscode ausführen, bevor er stirbt.
Dieser Thread führt eine Schleife aus, während die Instanzvariable continue wahr ist. Setzen Sie diese Variable auf "false", und der Thread stirbt auf natürliche Weise:
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