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