Mam następujący kod (from a Ruby tutorial):Pętle w wielu wątków
require 'thread'
count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
count1 += 1
count2 += 1
end
end
spy = Thread.new do
loop do
difference += (count1 - count2).abs
end
end
sleep 1
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"
counter.join(2)
spy.join(2)
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"
To przykład za korzystanie Mutex.synchronize
. Na moim komputerze wyniki różnią się znacznie od samouczka. Po wywołaniu join
, liczy się to czasami równa:
count1 : 5321211
count2 : 6812638
difference : 0
count1 : 27307724
count2 : 27307724
difference : 0
a czasami nie:
count1 : 4456390
count2 : 5981589
difference : 0
count1 : 25887977
count2 : 28204117
difference : 0
Nie rozumiem, jak to jest możliwe, że różnica jest jeszcze 0
choć liczy pokazują bardzo różne liczby.
Operacja add
prawdopodobnie wygląda tak:
val = fetch_current(count1)
add 1 to val
store val back into count1
i coś podobnego do count2
. Ruby może przełączać wykonywanie między wątkami, więc może nie zakończyć zapisu do zmiennej, ale gdy procesor wróci do wątku, powinien kontynuować od linii, w której został przerwany, prawda?
I wciąż jest tylko jeden wątek, który zapisuje do zmiennej. Jak to możliwe, że wewnątrz bloku loop do
jest wykonywany znacznie więcej razy?
co ma zrobić 'join (2)'? – uday
daje wątkowi limit (w sekundach) do zakończenia. jeśli tego nie nazwiem, ruby będzie automatycznie pobierał wątki po dojściu do końca programu (tak, że nieskończone 'loop do' zawsze się skończy). zobacz http://www.ruby-doc.org/core-1.9.3/Thread.html#method-i-join, aby uzyskać więcej informacji. – Tombart
To interesujące. W rubinach 1.8 "różnica" zawsze wynosi <> 0, a liczba ta nigdy się nie różni o więcej niż 1, ale w przypadku ruby 1.9 "różnica" jest zawsze równa == 0, ale liczba1 i liczba2 są daleko od siebie. – Casper