Ruby Language
Tråd
Sök…
Grundläggande tråd Semantik
En ny tråd separat från huvudtrådens körning kan skapas med hjälp av Thread.new
.
thr = Thread.new {
sleep 1 # 1 second sleep of sub thread
puts "Whats the big deal"
}
Detta startar automatiskt exekveringen av den nya tråden.
För att frysa exekveringen av huvudtråden, tills den nya tråden slutar, använd join
:
thr.join #=> ... "Whats the big deal"
Observera att tråden kanske redan är klar när du ringer gå med, i vilket fall körningen fortsätter normalt. Om en undertråd aldrig sammanfogas och huvudtråden slutförs, kör inte undertråden någon återstående kod.
Åtkomst till delade resurser
Använd en mutex för att synkronisera åtkomst till en variabel som nås från flera trådar:
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
Annars kan värdet på counter
närvarande är synlig för en tråd ändras av en annan tråd.
Exempel utan Mutex
(se t.ex. Thread 0
, där Before
och After
skiljer sig mer än 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
Exempel med 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
Hur man dödar en tråd
Du ringer använda Thread.kill
eller Thread.terminate
:
thr = Thread.new { ... }
Thread.kill(thr)
Avsluta en tråd
En tråd avslutas om den når slutet av kodblocket. Det bästa sättet att avsluta en tråd tidigt är att övertyga den att nå slutet av kodblocket. På så sätt kan tråden köra rensningskod innan den dör.
Denna tråd kör en slinga medan instansvariabeln fortsätter är sant. Ställ in denna variabel till falsk, och tråden dör en naturlig död:
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