共享/獨佔鎖定,又稱為讀取/寫入鎖定。
- E
- N
- S
- Y
- MonitorMixin
類別公開方法
new() 連結
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 50 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 148 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 159 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 76 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 114 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
(且目前持有鎖定)的執行緒呼叫。
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 96 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
stop_sharing() 連結
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 131 def stop_sharing synchronize do if @sharing[Thread.current] > 1 @sharing[Thread.current] -= 1 else @sharing.delete Thread.current @cv.broadcast end end end
yield_shares(purpose: nil, compatible: [], block_share: false) 連結
執行提供的區塊時暫時放棄所有持有之 Share 鎖定,允許任何 compatible
獨佔鎖定要求繼續進行。
來源: 顯示 | 在 GitHub 上