为什么Ruby中的数组操作不是primefaces的?
在Ruby中,如果array
被许multithreading修改,则此代码不是线程安全的:
array = [] array << :foo # many threads can run this code
为什么<<
操作不是线程安全的?
当你对它应用<<
操作时, array
是你的程序变量。 它分三步进行:
- 首先将变量复制到CPU寄存器中。
- CPU执行计算。
- CPU将结果写回变量存储器。
因此,这种高级单一操作分三步执行。 在这些步骤之间,由于线程上下文切换,其他线程可能读取变量的相同(旧)值。 这就是为什么它不是primefaces操作。
如果有多个线程访问同一个数组,请使用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
实际上使用MRI(Matz的Ruby实现)GIL(全局解释器锁)使任何纯C函数primefaces。
由于Array#<<
在MRI中实现为纯C代码,因此该操作将是primefaces的。 但请注意,这仅适用于MRI。 在JRuby上,事实并非如此。
为了完全理解发生了什么,我建议你阅读这两篇文章,它们很好地解释了一切:
没有人理解GIL
没有人理解GIL - 第2部分
因为Ruby是一种非常高级的语言,所以在操作系统级别上没有什么是真正的primefaces。 只有非常简单的assembly操作在操作系统级别是primefaces的(取决于操作系统),并且每个Ruby操作,即使是简单的1 + 1
对应于执行的数百或数千个assembly指令,例如方法查找,垃圾收集,对象初始化,范围计算等
如果您需要使操作成为primefaces,请使用互斥锁。
只是从@Linuxios和@TheTinMan开始:高级语言(HLL)操作通常不是primefaces的。 primefaces性(通常)不是单线程程序中的问题。 在multithreading程序中,您(程序员)必须以比单个HLL操作更高的粒度来推理它,因此具有primefaces的单独HLL操作实际上对您没有那么大的帮助。 另一方面,尽管使HLL操作primefaces在前后只需要几个机器指令 – 至少在现代硬件上 – 静态(二进制大小)和动态(执行时间)开销加起来。 更糟糕的是,显式primefaces性几乎会禁用所有优化,因为编译器无法跨primefaces操作移动指令。 没有真正的好处+显着的成本=非首发。