YARV 数组的 push/pop 方法是线程安全的吗?

Are YARV Arrays' push/pop methods thread-safe?

假设我有一对(生产者、消费者)YARV 线程(TpTc)共享一个 Array q - Tp 推送到 qTc 从中弹出。如果压入和弹出的执行顺序不重要,代码是否可以在没有任何同步机制的情况下工作?

由于其全局解释器锁 (GIL),大多数时候访问数组在 MRI/YARV 中是线程安全的(并且仅在那里),因此大多数情况下是偶然的。

您仍然必须确保每次只执行一个操作并避免 read/write 构造。在其他 Ruby 实现中,如 Rubinius 或 JRuby,数组显然不是线程安全的。

话虽如此,Ruby 附带了一个不同的线程间通信原语,巧合的是 MRI/VARV 中唯一的 class 是明确的线程-安全:Queue。它支持以线程安全的方式推送和弹出对象。

以 Ruby 的文档为例:

queue = Queue.new

producer = Thread.new do
  5.times do |i|
     sleep rand(i) # simulate expense
     queue << i
     puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
     value = queue.pop
     sleep rand(i/2) # simulate expense
     puts "consumed #{value}"
  end
end

还有一个名为 concurrent-ruby 的维护良好的项目,它为跨线程的并发编程提供了许多强大的原语。