Sła*_*osz 14 ruby multithreading atomic thread-safety atomicity
在Ruby中,如果array
被许多线程修改,则此代码不是线程安全的:
array = []
array << :foo # many threads can run this code
Run Code Online (Sandbox Code Playgroud)
为什么<<
操作不是线程安全的?
array
当你应用类似的操作时<<
,它是你的程序变量.它分三步进行:
因此,这种高级单一操作分三步执行.在这些步骤之间,由于线程上下文切换,其他线程可能读取变量的相同(旧)值.这就是为什么它不是原子操作.
实际上使用MRI(Matz的Ruby实现)GIL(全局解释器锁)使任何纯C函数原子化.
由于Array#<<
在MRI中实现为纯C代码,因此该操作将是原子的.但请注意,这仅适用于MRI.在JRuby上,情况并非如此.
为了完全理解发生了什么,我建议你阅读这两篇文章,这些文章很好地解释了一切:
如果有多个线程访问同一个数组,请使用Ruby的内置Queue类.它很好地处理生产者和消费者.
这是文档中的示例:
require 'thread'
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
consumer.join
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4330 次 |
最近记录: |