Deadlock producer consumer

Hi
I make the following test

#--------------------------------------------------
ProducerQueue = Containers::PriorityQueue.new
ConsumerQueue = Containers::Queue.new

mutex = Mutex.new
access = ConditionVariable.new

initialize ProducerQueue

producer = Thread.new do
loop do
mutex.synchronize {
while ProducerQueue.empty? do access.wait(mutex) end

ProducerQueue.pop
somework
ConsumerQueue.push(result)
access.signal

}
end
end
consumer = Thread.new do
loop do
mutex.synchronize {
while ConsumerQueue.empty? do access.wait(mutex) end

page = ConsumerQueue.pop()
somework
ProducerQueue.push(result)
access.signal

}
end
end

consumer.join
producer.join
#----------------------------------------------------------

I keep having deadlock when executing it
What is wrong with the code? I think may be I have to add an other
ConditionVariable, the problem is the producer and the consumer use the
two queues

Any Ideas?

On 10/14/2011 05:42 PM, rubix Rubix wrote:

 access.signal
 ProducerQueue.push(result)

I keep having deadlock when executing it
What is wrong with the code? I think may be I have to add an other
ConditionVariable, the problem is the producer and the consumer use the
two queues

Any Ideas

When you use mutex.synchronize, it’s going to lock to mutex. When you
call access.wait(), it releases that same mutex and waits for the mutex
to be unlocked. But you have already locked it, and it should/can not
unlock until after the block is finished. I’m not even sure what the
behavior is here, but it’s unlikely to work as you might expect.

-Justin

On Oct 14, 2011, at 5:42 PM, rubix Rubix wrote:

I keep having deadlock when executing it

What is wrong with the code? I think may be I have to add an other
ConditionVariable, the problem is the producer and the consumer use the
two queues

Is there any reason you’re not using Queue?

queue = Queue.new

consumer = Thread.start do
loop do
queue.enq produce_value
end
end

producer = Thread.start do
loop do
consume_value queue.deq
end
end

I need to use Priority queue
so I can dequeue the item with the highest priority first

I tried simple Queue and it doesn’t work too
because I think it a circular wait, the consumer consume from a queue
but produce new data and push them to the other queue
the producer make the same thing too
and i think that’s why I have deadlock but I don’t know how to solve the
problem

On Sat, Oct 15, 2011 at 3:26 PM, rubix Rubix [email protected]
wrote:

I tried simple Queue and it doesn’t work too
because I think it a circular wait, the consumer consume from a queue
but produce new data and push them to the other queue
the producer make the same thing too
and i think that’s why I have deadlock but I don’t know how to solve the
problem

Is this the kind of behaviour you’re looking for?

require ‘thread’

producer_queue = Queue.new
consumer_queue = Queue.new

def log(*a)
STDERR.print a.inspect + “\n”
end

producer = Thread.start do
loop do
log :producer, :pop
item = producer_queue.pop
log :producer, :item, item
item[:producer] += 1
log :producer, :push, item
consumer_queue.push(item)
end
end

consumer = Thread.start do
loop do
log :consumer, :pop
item = consumer_queue.pop
log :consumer, :item, item
item[:consumer] += 1
log :consumer, :push, item
producer_queue.push(item)
end
end

start things off

producer_queue.push({ :producer => 0, :consumer => 0})

either will work

#consumer_queue.push({ :producer => 0, :consumer => 0})

consumer.join
producer.join

Regards,
Sean

On Sat, Oct 15, 2011 at 9:52 PM, rubix Rubix [email protected]
wrote:

and
That’s just to show that the producer and consumer threads are
processing the item as it gets passed back and forth.


start things off

producer_queue.push({ :producer => 0, :consumer => 0})

either will work

#consumer_queue.push({ :producer => 0, :consumer => 0})

You need at least one item in either queue to get the ball rolling.

Regards,
Sean

I still have the deadlock problem
but I have some exceptions in somework of the produced values,
is unhandeled exception can be a cause of the deadlock?

thanks Sean,

I have a version with PriorityQueue from algorithms gem to pop the item
with the highest priority first but I had the problem of deadlock
but I tried today before your post a version with two standard queue but
it doesn’t work too,
I don’t know why you add the lines :

item[:consumer] += 1

and

start things off

producer_queue.push({ :producer => 0, :consumer => 0})

either will work

#consumer_queue.push({ :producer => 0, :consumer => 0})

I’ll try this version and see if it works

regards,

2011/10/16 rubix Rubix [email protected]:

is unhandeled exception can be a cause of the deadlock?

It can stop its thread, so yes.

– Matma R.