回答
array
是你的程序變量,當你應用像<<
這樣的操作。它發生在三個步驟中:
- 該變量首先被複制到CPU寄存器中。
- CPU執行計算。
- CPU將結果寫回變量存儲器。
所以這個高級單操作分三步進行。在這些步驟之間,由於線程上下文切換,其他線程可能會讀取變量的相同(舊)值。這就是爲什麼它不是原子操作。
由於Ruby是一個非常高層次的語言,什麼都不是在操作系統級別真正原子化。只有非常簡單的彙編操作在操作系統級別是原子操作(取決於操作系統),每個Ruby操作(即使是簡單的操作)都對應於數百或數千個執行的彙編指令,例如方法查找,垃圾收集,對象初始化,範圍計算等。
如果您需要使操作原子化,請使用互斥鎖。
如果您有多個線程訪問同一個陣列,請使用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(馬茨的Ruby實現)的GIL(全局解釋器鎖)作出任何純C函數的原子。
由於Array#<<
在MRI中被實現爲純C代碼,因此該操作將是原子操作。但請注意,這僅適用於MRI。在JRuby上,情況並非如此。
要完全瞭解正在發生的事情,我建議你閱讀這兩篇文章,這說明了一切非常好:
Nobody Understands the GIL
Nobody Understands the GIL - part 2
就riffing關閉@Linuxios和@TheTinMan的:高層語言(HLL)操作通常不是原子的。原子性(通常)不是單線程程序中的問題。在多線程程序中,你(程序員)必須以比單個HLL操作更高的粒度來推理它,因此單獨的HLL操作實際上對你沒有多大幫助。另一方面,儘管至少在現代硬件—之前和之後使得HLL操作原子只需要幾條機器指令,但靜態(二進制大小)和動態(執行時間)開銷相加。更糟的是,顯式原子性幾乎禁用了所有優化,因爲編譯器無法在原子操作之間移動指令。沒有真正的收益+顯着的成本=非首發。
- 1. THREE.Camera.prototype.lookAt</ <() -</ <是什麼意思?
- 2. 什麼是我的檔案中的「<<<<<<< head」?
- 3. 什麼是PHP中的「<<< SQL」?
- 4. PHP操作<<<
- 5. 操作<<爲QString的
- 6. 這是什麼算子<<< bash
- 7. 什麼是Swift上的+++和<<<?
- 8. Php <<<是什麼意思?
- 9. 爲什麼「testScores [」dave「]」的類型是「可選<Array<Int>> .Type」而不是「<Array<Int>> .Type」
- 10. 什麼意思的符號在java中「<<<」「<< =」「<<」
- 11. <%$,<%@,<%=,<%#...這是怎麼回事?
- 12. 爲什麼在操作符<exists時定義lt lt?
- 13. Ruby中的「<< - 」是什麼意思?
- 14. 「1000 << 16」中的「<<」是什麼意思?
- 15. git「<<<<<<< HEAD」
- 16. 「<<<<<<< HEAD」模板
- 17. 爲什麼不使用<< EOF代替cat << EOF?
- 18. 什麼是C#中的「| =」運算符? |在C#「=」操作</p> <pre><code>Status |= (int)states.Reading; </code></pre> <p>什麼是:
- 19. 的Java <<操作
- 20. 如何使操作符的左操作數<<一個函數?</p> <pre><code>Integer obj; obj << 5 << 3 << 2; </code></pre> <p>精細:
- 21. Heredoc <<<或<<?
- 22. wcout << L是什麼?
- 23. <<做什麼?
- 24. 什麼` 「</p> <pre><code>__m_uvm_status_container.scope.set_arg_element(`"ARG`",i); </code></pre> <p>什麼的<code>"ARG</code>在宏SV
- 25. 如</p> <p><code><p>This is text </p></code>或<code><div></code>或<code>This is text</code></p> <p>使用<code>XmlPullParser</code>檢索URL
- 26. 爲什麼輸出cout << setprecision(2)<< 0.999是1而不是1.0?
- 27. operator <<:std :: cout << i <<(i << 1);
- 28. 使用<<操作者
- 29. 爲什麼<textarea>顯示<>而不是< >?
- 30. 什麼是什麼是一個使用</p> <p><code>javac -cp classes helloworld.java</code></p> <p>和</p> <p><code>javac -classpath classes helloworld.java</code></p> 在CMD <p>的區別-cp和-classpath
您可能會喜歡閱讀:[** Ruby原子操作**](http://moonbase.rydia.net/mental/blog/programming/atomic-operations-in-ruby.html) –
你讀過了嗎?這個? [更新於Jörg's 2011年9月的評論](http://stackoverflow.com/questions/56087/does-ruby-have-real-multithreading/57802#57802) –
@theTinMan非常感謝!我的英語很差:(但我注意到你的和以前的編輯到我的答案,我會改善下一個答案。謝謝! –