Ruby simple race state question

I came across this example race condition:

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

Streams are launched in pararell, and it is possible that although one stream reads the value of the sum, the other completes its increase, but the first will already complete its own increment with the old value, and as a result, the sum will not change.

But I was wondering why, when I replace the string "sum = inc (sum)" with "sum + = 1", the result seems to be correct.

Why is this?

Is it because the overhead of calling a method is so great compared to just doing a variable job, and therefore some threads "go out of sync", causing the wrong output?

, + = 1 , ..?

+5
1

, , , , " ", ?

. , . 100_000.times :

$ seq 5 | xargs -L 1 ruby a.rb 100000
451167
472581
464413
442191
454204

, , , ?

, , Ruby ( , , ). ; , .

+3

All Articles