gpt4 book ai didi

ruby - 为什么 Ruby 中没有竞争条件

转载 作者:数据小太阳 更新时间:2023-10-29 07:38:55 25 4
gpt4 key购买 nike

我正在试验多线程示例。我正在尝试使用以下代码产生竞争条件。但我总是得到相同(正确)的输出。

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

最佳答案

这是因为 MRI Ruby 线程由于 GIL 而不是真正并行的(参见 here ),在 CPU 级别它们一次执行一个。

线程中的每个命令一次执行一个,因此每个线程中的 @count 始终正确更新。

可以通过添加另一个变量来模拟竞争条件,例如:

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

给出了一个很好的竞争条件示例 here , 为完整起见复制如下

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)

Here's the result I see from running this on MRI 2.0 several times.

$ ruby check_then_set.rb => shearing...

$ ruby check_then_set.rb => shearing... shearing...

$ ruby check_then_set.rb => shearing... shearing...

Sometimes the same sheep is being shorn twice!

关于ruby - 为什么 Ruby 中没有竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40454564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com