Я сталкивался с этим примером условия гонки:
def inc(n)
n + 1
end
sum = 0
threads = (1..10).map do
Thread.new do
10_000.times do
sum = inc(sum)
end
end
end
threads.each(&:join)
p sum
Потоки работают в pararell, и есть вероятность, что, пока один поток читает значение суммы, другой завершает его приращение, но первый собираетсязакончите свое собственное увеличение со старым значением, и в результате сумма не изменится.
Но мне было интересно, почему, когда я заменяю строку «sum = inc (sum)» на «sum + = 1», вывод кажется всегда правильным.
Почему это так??
Это потому, что накладные расходы на вызов метода настолько велики по сравнению с простым присваиванием переменной, и, следовательно, некоторые потоки «не синхронизируются», что приводит к неправильному выводу?Предположим, что даже с прямой суммой + = 1 я все еще смог бы наблюдать состояние гонки, но только если бы я делал намного более длинный цикл суммирования и т. д .?