# MonitorMixin

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

## 例

    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 は初期化される必要があります。 上の例のように Object#extend を使って利用する場合は 自動的に初期化されます。

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

しかし、MonitorMixin をクラス定義の際に Module#include を使って 利用する場合は、initialize メソッドで super() を呼んで、初期化する必要があります。 super だと ArgumentError になります。super と 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]

## メソッド

`mon_enter`

  モニターをロックします。一度に一つのスレッドだけがモニターをロックできます。 Mutex#lock に相当します。返り値は不定です。 Mutex#lock と違うのは現在のモニターの所有者が現在実行されているスレッドである場合、 何度でもロックできる点です。ロックした回数だけ mon_exit を呼ばなければモニターは 解放されません。

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

  Mutex#lock ではデッドロックが起きます。

      require 'thread'
      m = Mutex.new
      m.lock
      m.lock # => deadlock; recursive locking (ThreadError)

`mon_exit`

  モニターのロックを解放します。mon_enter でロックした回数だけ mon_exit を 呼ばなければモニターは解放されません。返り値は不定です。

  モニターが解放されればモニターのロック待ちになっていたスレッドの実行は 再開されます。

`mon_synchronize { ... }`
`synchronize { ... }`

  モニターをロックし、ブロックを実行します。実行後に必ずモニターのロックを開放します。

`mon_try_enter`

  モニターを開始しようとして成功した場合、true を返します。 つまりモニターしているスレッドがいないか、モニターしているのがスレッドが 現在のスレッドの場合に true を返します。

`new_cond`

  新しい MonitorMixin::ConditionVariable を生成して返します。

links: [Module] [MonitorMixin::ConditionVariable] [Mutex] [Object] [メソッド呼び出し]
reverse links: [Monitor] [MonitorMixin::ConditionVariable] [Rinda::TupleSpace] [monitor.rb]