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