簡體   English   中英

Ruby線程安全的線程創建

[英]Ruby thread safe thread creation

我今天遇到了這段代碼:

@thread ||= Thread.new do
  # this thread should only spin up once
end

它被多個線程調用。 我擔心如果多個線程正在調用此代碼,由於@thread訪問未同步,您可能會創建多個線程。 但是,有人告訴我,由於全局解釋器鎖定,這不可能發生。 我做了一些關於Ruby中線程的閱讀,看來運行Ruby代碼的單個線程可能會被其他線程搶占。 如果是這種情況,您是否不能像這樣進行交錯:

Thread A             Thread B
========             ========
Read from @thread    .
Thread.New           .
[Thread A preempted] .
.                    Read from @thread
.                    Thread.New
.                    Write to @thread
Write to @thread

另外,由於對@thread的訪問未同步, @thread保證對@thread寫入對所有其他線程可見? 除非您使用原子,互斥鎖等同步訪問該內存,否則我過去使用的其他語言的內存模型不能保證對內存寫入的可見性。

我仍在學習Ruby,並且意識到要理解Ruby中的並發性還有很長的路要走。 任何幫助,將不勝感激!

您需要一個互斥鎖。 本質上,GIL保護您免受攻擊的唯一一件事就是訪問未初始化的內存。 如果Ruby中的某些東西可以被很好地定義而不是原子的,那么您不應該假定它是原子的。

一個簡單的示例說明您可以進行示例排序。 每次運行時,都會收到“雙重設置”消息:

$global = nil
$thread = nil

threads = []

threads = Array.new(1000) do
  Thread.new do
    sleep 1
    $thread ||= Thread.new do
      if $global
        warn "double set!"
      else
        $global = true
      end
    end
  end
end

threads.each(&:join)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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