[Qt-interest] QMutex deadlock without using QMutex

André Somers andre at familiesomers.nl
Tue Apr 27 21:07:15 CEST 2010


Hi Gabriel,

Thanks for letting me pick your brain here...

-----Oorspronkelijk bericht-----
Van: Gabriel M. Beddingfield [mailto:gabrbedd at gmail.com] 
Verzonden: dinsdag 27 april 2010 20:25
Aan: Andre Somers
CC: Qt-interest
Onderwerp: Re: [Qt-interest] QMutex deadlock without using QMutex



On Tue, 27 Apr 2010, Andre Somers wrote:

>>> You said that the worker threads signal the coordinator thread.  In
>>> response to this signal, the coordinator thread signals the workers.
>>> Right?
>> Yes. When a worker signals the coordinator, the coordinator, after some
>> other work, signals the worker(s) that are currently not bussy to start
>> processing a new work package, as long as there is still work to be done.
>
> So, are all the calcs implemented in a slot?  And that 
> slot... does it then emit a signal back to the coordinator?
Yes, and yes.

>> Good question. I'm not a 100% sure. What I *expect* to happen, is the
>> same that happens with any event in Qt: that that signal is not
>> delivered untill the coordinator thread has returned to the eventloop.
>> That would mean that the coordinator thread is in a consistent state at
>> all times, since the work it is doing can not be interupted. Since the
>> signals are queued, they are marchalled through the eventloop, right?
>> That's the reason I opted to use queued connections in the first place.
>
> So, when all these events are marshalled in a queue... it 
> sounds like you're assuming that the threads won't change 
> /their/ states.  For example:
>
>    1 Coordinator::queue_worker()
>    2 {
>    3    foreach(workerthread as w) {
>    4       if(! w->working() ) {
>    5           w->queue_more_work();
>    6       }
>    7    }
>    8 }
>    9
>    10 WorkerThread::queue_more_work()
>    11 {
>    12    _working = true;
>    13    //...
>    14 }
>
> This code here has a race condition.  Between the execution 
> of lines 4 and 5... it's possible that line 12 could be 
> executed... which is the type of situation that could lead 
> to a deadlock. 

Hmmm... interesting suggestion. However, as you said yourself above:
The calculation is triggered through a queued signal/slot connection too
(well, a QMetaObject::invokeMethod call with the Qt::QueuedConnection flag
set to be exact.) They are not called directly as you do above. 
Would that not mean that just like for the coordinator thread, the worker
threads are not interrupted, as the slot would only be invoked when the
worker thread returns to the eventloop? Also: I don't see the deadlock in
your example above. How could line 12 be executed between line 4 and 5? Once
the worker thread signals that it is ready, the method exits and the thread
returns to the eventloop.

> Anyway... as I said, deadlocks are tough to solve.  I've 
> never had one that could be solved on a mailing list, 
> either.  I've always had to think way outside of the box. 
> Also, the odds are that it's /your/ bug and not Qt's.  :-)

Yes, that is my assumption as well. I absolutely assume that it is my
mistake, not Qt's.

> Let me know if I can help any more.
I really appreciate your input. Thanks!

André





More information about the Qt-interest-old mailing list