假设我有一对(生产者,消费者)YARV线程(Tp
,Tc
)共享Array
q
-Tp
推送到{ {1}},然后弹出q
。如果执行下推和弹出操作的顺序并不重要,那么代码是否可以在没有任何同步机制的情况下工作?
答案 0 :(得分:2)
由于其全局解释器锁(GIL),因此在大多数情况下访问数组在MRI / YARV中(并且仅在那儿)是线程安全的,
您仍然必须确保每次仅执行一次操作,并避免读/写结构。在Rubinius或JRuby之类的其他Ruby实现中,数组显然不是线程安全的。
话虽如此,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的维护良好的项目,该项目为跨线程并发编程提供了许多强大的原语。