goy*_*kit 12 ruby multithreading
我正在尝试多线程示例.我正在尝试使用以下代码生成竞争条件.但我总是得到相同(正确)的输出.
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
Run Code Online (Sandbox Code Playgroud)
我能够在每个线程中使用少得多的迭代次数来观察Java中的竞争条件.是不是我没有足够多次运行它来产生竞争条件,或者+/ -是Ruby中的线程安全?我使用的是ruby 2.0.0p247
tih*_*hom 13
这是因为MRI Ruby线程由于GIL而不是真正的并行(参见此处),在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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
这是我在MRI 2.0上多次运行时看到的结果.
$ ruby check_then_set.rb =>剪毛......
$ ruby check_then_set.rb =>剪切...剪切......
$ ruby check_then_set.rb =>剪切...剪切......
有时同样的羊被剪了两次!
| 归档时间: |
|
| 查看次数: |
1927 次 |
| 最近记录: |