模組 MonitorMixin
在並行程式設計中,監視器是一個物件或模組,旨在讓多個執行緒安全地使用。監視器的定義特性是其方法以互斥方式執行。也就是說,在每個時間點,最多只有一個執行緒可以執行其任何方法。與推理更新資料結構的平行程式碼相比,這種互斥極大地簡化了對監視器實作的推理。
您可以在 Wikipedia 的 監視器 頁面上閱讀有關一般原理的更多資訊。
範例¶ ↑
簡單的物件.extend¶ ↑
require 'monitor.rb' buf = [] buf.extend(MonitorMixin) empty_cond = buf.new_cond # consumer Thread.start do loop do buf.synchronize do empty_cond.wait_while { buf.empty? } print buf.shift end end end # producer while line = ARGF.gets buf.synchronize do buf.push(line) empty_cond.signal end end
消費者執行緒等待生產者執行緒將一行推送到 buf,同時 buf.empty?
。生產者執行緒(主執行緒)從 ARGF
讀取一行並將其推送到 buf,然後呼叫 empty_cond.signal
以通知消費者執行緒有新資料。
簡單的 類別
include¶ ↑
require 'monitor' class SynchronizedArray < Array include MonitorMixin def initialize(*args) super(*args) end alias :old_shift :shift alias :old_unshift :unshift def shift(n=1) self.synchronize do self.old_shift(n) end end def unshift(item) self.synchronize do self.old_unshift(item) end end # other methods ... end
SynchronizedArray
實作一個 陣列
,其中包含對項目進行同步存取。此 類別
實作為 陣列
的子類別,其中包含 MonitorMixin
模組。
公開類別方法
extend_object(obj) 按一下以切換來源
呼叫超類別方法
# File ext/monitor/lib/monitor.rb, line 152 def self.extend_object(obj) super(obj) obj.__send__(:mon_initialize) end
new(...) 按一下以切換來源
使用 extend MonitorMixin
或 include MonitorMixin
取代此建構函式。請參閱上面的範例以了解如何使用此模組。
呼叫超類別方法
# File ext/monitor/lib/monitor.rb, line 222 def initialize(...) super mon_initialize end
公開執行個體方法
mon_enter() 按一下以切換來源
進入獨佔區段。
# File ext/monitor/lib/monitor.rb, line 169 def mon_enter @mon_data.enter end
mon_exit() 按一下以切換來源
離開獨佔區段。
# File ext/monitor/lib/monitor.rb, line 176 def mon_exit mon_check_owner @mon_data.exit end
mon_locked?() 按一下以切換來源
如果此監視器被任何執行緒鎖定,則傳回 true
# File ext/monitor/lib/monitor.rb, line 184 def mon_locked? @mon_data.mon_locked? end
mon_owned?() 按一下以切換來源
如果此監視器被目前執行緒鎖定,則傳回 true。
# File ext/monitor/lib/monitor.rb, line 191 def mon_owned? @mon_data.mon_owned? end
mon_synchronize(&b) 按一下以切換來源
進入獨佔區段並執行區塊。區塊結束時自動離開獨佔區段。請參閱 MonitorMixin
下的範例。
# File ext/monitor/lib/monitor.rb, line 200 def mon_synchronize(&b) @mon_data.synchronize(&b) end
別名為:synchronize
mon_try_enter() 按一下以切換來源
嘗試進入獨佔區段。如果鎖定失敗,則傳回 false
。
# File ext/monitor/lib/monitor.rb, line 160 def mon_try_enter @mon_data.try_enter end
別名為:try_mon_enter
new_cond() 按一下以切換來源
建立一個新的 MonitorMixin::ConditionVariable
,並與 Monitor
物件關聯。
# File ext/monitor/lib/monitor.rb, line 209 def new_cond unless defined?(@mon_data) mon_initialize @mon_initialized_by_new_cond = true end return ConditionVariable.new(@mon_data) end
私人實例方法
mon_check_owner() 按一下以切換來源
# File ext/monitor/lib/monitor.rb, line 241 def mon_check_owner @mon_data.mon_check_owner end
mon_initialize() 按一下以切換來源
在包含於類別中或物件已使用 MonitorMixin
擴充後,初始化 MonitorMixin
# File ext/monitor/lib/monitor.rb, line 229 def mon_initialize if defined?(@mon_data) if defined?(@mon_initialized_by_new_cond) return # already initialized. elsif @mon_data_owner_object_id == self.object_id raise ThreadError, "already initialized" end end @mon_data = ::Monitor.new @mon_data_owner_object_id = self.object_id end