From: "Hal E. Fulton" Date: 2001-03-06T16:22:32+09:00 Subject: [ruby-talk:12099] (My) Thread bug - sync != lock/unlock Hello all, I recently made an "improvement" to a little piece of code... and it quit working. (I call that "rebugging." Yeah, YOU'VE never done it. Right...) I really thought this code was correct... I was implementing a protected queue for a simple producer-consumer problem. (Yes, I know about the existing one. This was an exercise.) I used a mutex and a pair of condition variables. At least, that's what I meant to do. Everything works fine in the code as shown. I even added a little extra delay to the consumer so the queue would get "fuller" -- that worked fine. But when I replace the lock/unlock sequences with a block passed to mutex.synchronize, it doesn't work anymore! What have I done wrong? Thanks much, Hal Fulton =========================== require "thread" class ProtectedBuffer def initialize(n) @max = n @buff = [] @mutex = Mutex.new @notFull = ConditionVariable.new @notEmpty = ConditionVariable.new end def enqueue x @mutex.lock while self.full? do @notFull.wait(@mutex) end @buff.push x @notEmpty.signal @mutex.unlock end def dequeue @mutex.lock while self.empty? do @notEmpty.wait(@mutex) end x = @buff.shift @notFull.signal @mutex.unlock return x end def empty? @buff.size == 0 end def full? @buff.size == @max end def size @buff.size end end # Main... buffer = ProtectedBuffer.new(10) producer = Thread.new do item = 0 loop do sleep rand 0 puts "Producer makes #{item}" buffer.enqueue item item += 1 end end consumer = Thread.new do loop do sleep (rand 0)+0.3 item = buffer.dequeue puts "Consumer retrieves #{item}" end end sleep 60 # Run a minute, then die and kill threads