type=class
superclass=Object
included=
extended=
library=thread

åɤƱΰĤǤѿ¸륯饹Ǥ

ʲ ConditionVariable 򤹤Τ˻ͤˤʤޤ

[[url:http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html#UF]]

=== Condition Variable Ȥ

륹å A ¾ΰưƤȤޤå A ϸ߶Ƥʤ
꥽ɬפˤʤäΤǶޤԤĤȤˤȤޤϤޤޤ
ʤʤ顢å A ¾ΰưƤ櫓Ǥ顢¾ΥåɤưȤ
Ǥޤ󡣥꥽뤳ȤǤޤ󡣥å A ꥽ζ
ԤäƤƤ⡢ĤޤǤȤϤޤ

ʾΤ褦ʾ褹Τ Condition Variable Ǥ

å a Ǿ(꥽Ƥ뤫ʤ)ޤ wait ᥽åɤ
åɤߤޤ¾Υå b ˤƾ郎줿ʤ signal
᥽åɤǥå a Фƾ郎ΩȤΤޤ줬ŵ^
Ǥ

    mutex = Mutex.new
    cv = ConditionVariable.new

    a = Thread.start {
        mutex.synchronize {
          ...
          while (郎ʤ)
            cv.wait(mutex)
          end
          ...
        }
    }

    b = Thread.start {
        mutex.synchronize {
          # ξ
          cv.signal
        }
    }

ʲ [[ruby-list:14445]] ǾҲ𤵤ƤǤ@q ˤʤä硢
뤤ˤʤä Condition Variable Ȥä wait Ƥޤ

  require 'thread'

  class TinyQueue
    def initialize(max=2)
      @max = max
      @full = ConditionVariable.new
      @empty = ConditionVariable.new
      @mutex = Mutex.new
      @q = []
    end

    def count
      @q.size
    end

    def enq(v)
      @mutex.synchronize{
        @full.wait(@mutex) if count == @max
        @q.push v
        @empty.signal if count == 1
      }
    end

    def deq
      @mutex.synchronize{
        @empty.wait(@mutex) if count == 0
        v = @q.shift
        @full.signal if count == (@max - 1)
        v
      }
    end

    alias send enq
    alias recv deq
  end

  if __FILE__ == $0
    q = TinyQueue.new(1)
    foods = 'Apple Banana Strawberry Udon Rice Milk'.split
    l = []

    th = Thread.new {
      for obj in foods
        q.send(obj)
        print "sent ", obj, "\n"
      end
      q.send nil
    }

    l.push th

    th = Thread.new {
      while obj = q.recv
        print "recv ", obj, "\n"
      end
    }
    l.push th

    l.each do |t|
      t.join
    end
  end

¹ԤȰʲΤ褦˽Ϥޤ

  $ ruby condvar.rb
  sent Apple
  recv Apple
  sent Banana
  recv Banana
  sent Strawberry
  recv Strawberry
  sent Udon
  recv Udon
  sent Rice
  recv Rice
  sent Milk
  recv Milk
