type=module
superclass=
included=
extended=
dynamically_included=
dynamically_extended=
library=monitor
aliases=
aliasof=

スレッドの同期機構としてのモニター機能を提供するモジュールです。

クラスに [[m:Module#include]] したり、オブジェクトに
[[m:Object#extend]] したりすることでそのクラス/オブジェクトに
モニタ機能を追加します。

=== 例
消費者、生産者問題の例
  require 'monitor'
    
  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

=== 初期化

MonitorMixin は初期化される必要があります。
上の例のように [[m:Object#extend]] を使って利用する場合は
自動的に初期化されます。

  require 'monitor'
  buf = []
  buf.extend(MonitorMixin)

しかし、MonitorMixin をクラス定義の際に [[m:Module#include]] を使って
利用する場合は、initialize メソッドで super() か super を呼んで、初期化する必要があります。
スーパークラスの initialize に引数を渡したい場合は super を、そうでない場合は super() を呼んで下さい。
詳しくは、[[ref:d:spec/call#super]] を参照して下さい。
例えば、以下の MyObject のスーパークラスは Object であり、その initialize は引数を受け付けないので
super ではなく super() を呼ぶ必要があります。

  require 'monitor'
  class MyObject
    include MonitorMixin
    
    def initialize(val)
      super()
      @value = val
    end
    
    def to_s
      synchronize {
        @value.to_s
      }
    end
  end

以下も参考になります。

  * [[ruby-dev:9384]]
  * [[ruby-dev:9386]]
