ruby简单竞争条件问题
我遇到了一个竞赛条件的例子:ruby简单竞争条件问题,ruby,multithreading,race-condition,Ruby,Multithreading,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 线程在pararell中运行,当一个线程读取sum的值时,另一个线程完成对它的递增,但前者即将使用旧值完成自己的递增,因此sum不会改变
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的值时,另一个线程完成对它的递增,但前者即将使用旧值完成自己的递增,因此sum不会改变
但我想知道,为什么当我将“sum=inc(sum)”行替换为“sum+=1”时,输出似乎总是正确的
为什么呢
是不是因为调用一个方法的开销比仅仅执行一个变量赋值要大得多,因此一些线程“失去同步”,导致输出不正确
我假设,即使是直和+=1,我仍然能够观察到竞争条件,但前提是我做了更长的求和循环,等等
是不是因为调用一个方法的开销比仅仅执行一个变量赋值要大得多,因此一些线程“失去同步”,导致输出不正确
对。要验证它,只需增加计数器并运行几个测试。我将其增加到100_000。乘以,结果如下:
$ seq 5 | xargs -L 1 ruby a.rb 100000
451167
472581
464413
442191
454204
嗯,看起来不太好,是吗
所以,是的,增量在Ruby中不是原子的(我怀疑有很多语言是这样的)。但是有助手类来实现这种行为;例如