为什么在Ruby中没有比赛条件 [英] Why no race condition in Ruby
问题描述
我正在尝试使用多线程示例.我正在尝试使用以下代码来产生竞争条件.但是我总是得到相同(正确)的输出.
I was experimenting with multithreading examples. I am trying to produce a race condition using the following code. But I am always getting the same (correct) output.
class Counter
attr_reader :count
def initialize
@count = 0
end
def increment
@count += 1
end
def decrement
@count -= 1
end
end
c = Counter.new
t1 = Thread.start { 100_0000.times { c.increment } }
t2 = Thread.start { 100_0000.times { c.increment } }
t1.join
t2.join
p c.count #200_0000
我能够使用每个线程中更少的迭代次数来观察Java中的竞争状况.是我运行的次数不足以产生竞争条件,还是+
/-
在Ruby中是线程安全的?我正在使用ruby 2.0.0p247
I am able to observe the race condition in Java using much less number of iterations in each thread. Is it that I am not running it enough number of times to produce a race condition, or +
/-
are Thread safe in Ruby? I am using ruby 2.0.0p247
推荐答案
This is because MRI Ruby threads are not really parallel due to GIL (see here), at CPU level they are executed one at a time.
一个线程中的每个命令一次执行一次,因此每个线程中的@count
总是正确更新.
Each command in a thread is executed one at a time hence @count
in each thread is always updated correctly.
种族条件可以通过添加另一个变量来模拟,例如:
Race condition can be simulated by adding another variable like:
class Counter
attr_accessor :count, :tmp
def initialize
@count = 0
@tmp = 0
end
def increment
@count += 1
end
end
c = Counter.new
t1 = Thread.start { 1000000.times { c.increment; c.tmp += 1 if c.count.even?; } }
t2 = Thread.start { 1000000.times { c.increment; c.tmp += 1 if c.count.even?; } }
t1.join
t2.join
p c.count #200_0000
p c.tmp # not 100_000, different every time
给出了一个很好的竞争条件示例此处,出于完整性考虑,复制在下方
A nice example of race condition is given here, copied below for completeness
class Sheep
def initialize
@shorn = false
end
def shorn?
@shorn
end
def shear!
puts "shearing..."
@shorn = true
end
end
sheep = Sheep.new
5.times.map do
Thread.new do
unless sheep.shorn?
sheep.shear!
end
end
end.each(&:join)
这是我在MRI 2.0上多次运行后看到的结果.
Here's the result I see from running this on MRI 2.0 several times.
$ ruby check_then_set.rb =>剪切...
$ ruby check_then_set.rb => shearing...
$ ruby check_then_set.rb =>剪切...剪切...
$ ruby check_then_set.rb => shearing... shearing...
$ ruby check_then_set.rb =>剪切... 剪切...
$ ruby check_then_set.rb => shearing... shearing...
有时候同一只羊被砍两次!
Sometimes the same sheep is being shorn twice!
这篇关于为什么在Ruby中没有比赛条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!