3

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

4

1 回答 1

3

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

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

话虽如此,Ruby 为线程间通信提供了不同的原语,巧合的是,它是 MRI/VARV 中唯一明确线程安全的类: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,它为跨线程的并发编程提供了许多强大的原语。

于 2018-08-13T19:27:07.720 回答