簡體   English   中英

Ruby中是否有任何保證/記錄為原子的操作/方法?

[英]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個部分。

http://www.jstorimer.com/blogs/workingwithcode/8100871-nobody-understands-the-gil-part-2-implementation

第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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM