gpt4 book ai didi

ruby - 线程安全 : Class Variables in Ruby

转载 作者:数据小太阳 更新时间:2023-10-29 06:23:31 24 4
gpt4 key购买 nike

在 Ruby 中对类变量执行写入/读取操作不是线程安全的。对实例变量执行写入/读取似乎是线程安全的。也就是说,对类或元类对象的实例变量执行写入/读取是否线程安全?

这三个(人为的)示例在线程安全方面有何区别?

示例 1:相互排斥

class BestUser # (singleton class)
@@instance_lock = Mutex.new

# Memoize instance
def self.instance
@@instance_lock.synchronize do
@@instance ||= best
end
end
end

示例 2:实例变量存储

class BestUser # (singleton class)
# Memoize instance
def self.instance
@instance ||= best
end
end

示例 3: METACLASS 上的实例变量存储

class BestUser # (singleton class)
# Memoize instance
class << self
def instance
@instance ||= best
end
end
end

最佳答案

例2和例3完全一样。模块和类也是对象,在一个对象上定义一个单例方法实际上是在它的单例类上定义它。

话虽如此,并且由于您已经确定实例变量访问是线程安全的,因此示例 2 和 3 也是线程安全的。例1应该也是线程安全的,但不如另外两个,因为它需要手动变量同步。

但是,如果您需要利用类变量在继承树中共享这一事实,您可能必须使用第一种方法。


Ruby 语言固有的线程安全性取决于实现。

MRI,在 1.9 之前,实现了线程 at the VM level .这意味着即使 Ruby 能够安排代码执行,但在单个 Ruby 进程中并没有真正并行运行。 Ruby 1.9 使用与 global interpreter lock 同步的 native 线程.只有持有锁的上下文才能执行代码。

n, x = 10, 0

n.times do
Thread.new do
n.times do
x += 1
end
end
end

sleep 1
puts x
# 100

x 的值在 MRI 上总是一致。然而,在 JRuby 上,情况发生了变化。同一算法的多次执行产生值 7687988894。结果可能是任何结果,因为 JRuby 使用 Java 线程,它们是真正的线程并并行执行。

就像在 Java 语言中一样,为了在 JRuby 中安全地使用线程,需要手动同步。以下代码始终为 x 生成一致的值:

require 'thread'
n, x, mutex = 10, 0, Mutex.new

n.times do
Thread.new do
n.times do
mutex.synchronize do
x += 1
end
end
end
end

sleep 1
puts x
# 100

关于ruby - 线程安全 : Class Variables in Ruby,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9558192/

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