一個共用/獨占鎖定,又稱為讀寫鎖定。
方法
- E
- N
- S
- Y
包含的模組
- MonitorMixin
類別公用方法
new() 連結
來源: 顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 49 def initialize super() @cv = new_cond @sharing = Hash.new(0) @waiting = {} @sleeping = {} @exclusive_thread = nil @exclusive_depth = 0 end
執行個體公用方法
exclusive(purpose: nil, compatible: [], after_compatible: [], no_wait: false) 連結
在取得獨占鎖定的同時,執行所提供的區塊。如果設定 no_wait
,而且鎖定無法立刻使用,會回傳 nil
而不進行讓與。否則,回傳區塊的結果。
請參閱 start_exclusive
以取得其他選項。
來源: 顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 147 def exclusive(purpose: nil, compatible: [], after_compatible: [], no_wait: false) if start_exclusive(purpose: purpose, compatible: compatible, no_wait: no_wait) begin yield ensure stop_exclusive(compatible: after_compatible) end end end
sharing() 連結
在取得共用鎖定的同時,執行所提供的區塊。
來源: 顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 158 def sharing start_sharing begin yield ensure stop_sharing end end
start_exclusive(purpose: nil, compatible: [], no_wait: false) 連結
如果設定 no_wait
,而且鎖定無法立刻使用,回傳 false。否則,在取得鎖定後回傳 true。
purpose
和 compatible
共同作用;當這個執行緒在等待獨占鎖定時,它會將共用 (若有) 讓與給其他嘗試,而這些嘗試的 purpose
出現在此嘗試的 compatible
清單中。這允許「鬆散」升級,這種升級並不那麼嚴格,可以防止某些類型的死結。
對於許多資源來說,鬆散升級已經足夠:如果一個執行緒正在等待鎖定,它不會執行任何其他程式碼。只要 purpose
相符,就可以只讓與給不互相干擾的執行緒。
來源: 顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 75 def start_exclusive(purpose: nil, compatible: [], no_wait: false) synchronize do unless @exclusive_thread == Thread.current if busy_for_exclusive?(purpose) return false if no_wait yield_shares(purpose: purpose, compatible: compatible, block_share: true) do wait_for(:start_exclusive) { busy_for_exclusive?(purpose) } end end @exclusive_thread = Thread.current end @exclusive_depth += 1 true end end
start_sharing() 連結
來源: 顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 113 def start_sharing synchronize do if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current # We already hold a lock; nothing to wait for elsif @waiting[Thread.current] # We're nested inside a +yield_shares+ call: we'll resume as # soon as there isn't an exclusive lock in our way wait_for(:start_sharing) { @exclusive_thread } else # This is an initial / outermost share call: any outstanding # requests for an exclusive lock get to go first wait_for(:start_sharing) { busy_for_sharing?(false) } end @sharing[Thread.current] += 1 end end
stop_exclusive(compatible: []) 連結
放棄獨占鎖定。只能呼叫呼叫 start_exclusive
的執行緒 (且目前保有鎖定) 來呼叫。
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 95 def stop_exclusive(compatible: []) synchronize do raise "invalid unlock" if @exclusive_thread != Thread.current @exclusive_depth -= 1 if @exclusive_depth == 0 @exclusive_thread = nil if eligible_waiters?(compatible) yield_shares(compatible: compatible, block_share: true) do wait_for(:stop_exclusive) { @exclusive_thread || eligible_waiters?(compatible) } end end @cv.broadcast end end end