From: shugo@... (Shugo Maeda) Date: 1998-02-25T00:32:58+09:00 Subject: [ruby-list:6735] Mutex/ConditionVariable/Queue 前田です。 今JavaでMutexとConditionVariableを作っているのですが、Rubyでも 使えると便利かなと思って作ってみました。 class ConditionVariable def initialize @waiters = [] @waiters_mutex = Mutex.new end def wait(mutex) mutex.unlock @waiters_mutex.synchronize { @waiters.push(Thread.current) } Thread.stop mutex.lock end def signal @waiters_mutex.synchronize { t = @waiters.shift t.run if t } end def broadcast @waiters_mutex.synchronize { for t in @waiters t.run end @waiters.clear } end end 試しにthread.rbのQueueをこれで書いてみました。 class Queue2 def initialize @que = [] @que_mutex = Mutex.new @que_cond = ConditionVariable.new end def push(obj) @que_mutex.synchronize { @que.push(obj) } @que_cond.signal end def pop(noblock = false) result = nil @que_mutex.synchronize { if @que.length == 0 and noblock raise ThreadError, "queue empty" end while @que.length == 0 @que_cond.wait(@que_mutex) end result = @que.shift } return result end def empty? @que.length == 0 end def length @que.length end alias size length end 以下のスクリプトで動作を確認しました。 queue = Queue2.new Thread.start { while s = queue.pop print s end } while line = gets queue.push(line) end で、ここから質問なのですが(^^;、 def pop(noblock = false) result = nil @que_mutex.synchronize { if @que.length == 0 and noblock raise ThreadError, "queue empty" end while @que.length == 0 @que_cond.wait(@que_mutex) end result = @que.shift } return result end の部分を def pop(noblock = false) @que_mutex.synchronize { if @que.length == 0 and noblock raise ThreadError, "queue empty" end while @que.length == 0 @que_cond.wait(@que_mutex) end return @que.shift } end とするとreturnのところでブロックするようなのですが、これは どうしてでしょうか。 # waitからは帰ってきているようです。 -- 前田 修吾