[英]Are there any operations/methods in Ruby that are guaranteed/documented to be atomic?
我做了一個快速的Google搜索,幾乎所有用Ruby編寫的關於原子性的文章都建議在該操作周圍包裹一個Mutex。 但是,我懷疑這種方法不能滿足原子性的通常定義,因為信號可能會中斷同步代碼。 例如(摘自Ruby Best Practices ):
lock = Mutex.new
# XXX this is an example of what NOT to do inside a signal handler:
trap(:USR1) do
lock.synchronize do
# if a second SIGUSR1 arrives here, this block of code
# will fire again. Attempting Mutex#synchronize twice
# the same thread leads to a deadlock error
end
end
據我所知,原子是高級語言不那么重要,但對於研究的緣故,我想獲得關於這個問題的規范答案與GIL的實現(例如MRI 2.0.0),並沒有如 JRuby的1.7.4,和Rubinius的1.2.4
我對這個主題的知識非常有限。 但我會盡力回答。
Jesse Storimer寫了一篇非常好的關於並發的文章。 我強烈建議您閱讀有關它的3個部分。
第2部分的結論是GIL保證本機C方法實現是原子的。
您給出的示例實際上是重入問題,而不是原子性。 我不知道那是同一件事還是緊密相關。
就像文章中解釋的那樣,ruby與事件驅動的編程不同,在事件驅動的編程中,回調是同步的,這意味着如果兩次發送信號USR1,則第二個處理程序將在第一個處理程序完成后執行。 因此,您不會兩次鎖定互斥鎖。
但是在紅寶石信號處理中是異步的。 表示兩次發送信號。 第二個處理程序將中斷第一個處理程序。 因為第一個處理程序已經獲取了鎖,所以第二個嘗試獲取相同的鎖的處理程序將引發異常。 而且我相信這個問題不是特定於紅寶石的。
解決此問題的方法之一是通過創建隊列進行信號處理。 對此的另一種解決方案是使用一種稱為“自管”技巧的方法。 兩種方法。 很棒的Jesse Storimer在本文中再次進行了解釋:
http://rubysource.com/the-self-pipe-trick-explained/
因此,對於MRI 2.0.0,我相信仍然具有GIL,因此ruby僅保證本機C方法是原子性的。
JRuby受JVM支持,因此我猜想所有線程和鎖定機制都在JVM之上實現
Rubinius 1.2也仍然具有GIL,因此我相信它將與MRI相同。 但是Rubinius 2.x刪除了GIL。 我在Rubinius上沒有太多經驗,所以我對此不太確定。
並回答問題,如果您正在使用ruby中的多線程應用程序。 互斥量類應注意,該塊一次只能由單線程執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.