共享/独占锁,也称为读/写锁。
方法
- 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
(并且当前持有锁)的线程调用。
源代码: 显示 | 在 GitHub 上
# 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
stop_sharing() 链接
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 130 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) 链接
在执行提供的代码块时,暂时放弃所有持有的共享锁,允许任何 compatible
独占锁请求继续进行。
源代码: 显示 | 在 GitHub 上