Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

Qt::BlockingQueuedConnection not waiting?



  • Hi all!!
    I am working developing software using -QT- Qt for almost 10 months, what an amazing framework!!

    Recently, I have faced a little problem using threads. Here is the issue:

    I have a class (e.g class A) with signals and slots declared. In my main thread I create my QApplication and an object of another class B. After that, I move that object to a secondary thread. During execution some signals of class A are emited called from the secondary thread (object B) so a slot of class A is executed in the QApplication thread).
    I am trying to synchronize this threads so, when this signal is emmited the emisor waits till the slot is executed (and finished). I suppose connecting using Qt::BlockingQueuedConnection will be enough, but I suspect that this kind of connection does not wait till the slot is finished just till the slot is called (the signal is attended).
    Is this correct? currently I am using Qt::QueuedConnection and synchronizing using QWaitCondition but it would be better (clear coding) if I can use the first option Qt::BlockingQueuedConnection Am I doing something wrong? Any suggestions would be appreciated, Thanks!!



  • Is the secondary thread running Thread::exec() ?



  • Yes it is.

    May be something about communicating a secondary thread with the main thread?
    In this case the main thread (QApp thread is executing an slot(painting things) connected to a signal emited from the secondary thread. This signal-slot is connected using Qt::BlockingQueuedConnection but it seems that the secondary thread is not waiting till the end of the slot.

    I hope to have clarified the example a bit.

    Thanks in advance.



  • According to this: http://doc.qt.nokia.com/latest/threads-qobject.html using Qt::BlockingQueuedConnection should behave as you describe: wait for the slot to complete before returning to execution in the thread emitting the signal.
    I don't understand this however:

    "During execution some signals of class A are emited called from the secondary thread (object B) so a slot of class A is executed in the QApplication thread)."

    Do you call signals on A from the secondary thread a->signalX() ?
    You should NOT do that. Signals should be emitted from the thread which has the object's affinity.

    If you need a signal to be emitted so that a slot on A is executed in the QApp thread, you should define this signal on B and then use a Qt::BlockingQueuedConnection

    @
    connect(b, SIGNAL(signalB()), a, SLOT(slotA()), Qt::BlockingQueuedConnection);
    @



  • Are you saying that this isn't supported or that you aren't aware if it's possible (e.g. calling emit a.signalX() on thread B when a is owned by thread A )? Barring the BlockingQueuedConnection type, I think what the OP proposes should work, in fact it's partially how I'm designing a component to work as well.

    The project is a library that operates on a singleton backend which runs many threads. The API is essentially thin client instances that register themselves with the backend upon creation and unregister upon destruction. The backend needs to signal particular instances (potentially across threads) based on different events in the background and specific API client requests.

    To my knowledge, there's no way to conditionally signal a particular object, which is a problem with Qt in my opinion. If what the OP proposes doesn't work, I'd think that I'll need to grab a hold of the target instance, connect a signal from the backend to a signal of the instance, emit my signal, and then disconnect the same signal. This all sounds like quite a hassle and when reading the documentation for Qt::AutoConnection, it suggests that the signal emitted is based on the thread it comes from, having mentioned nothing to do with the object that emitted it. This could just be a documentation inconsistency, but if you ask me, my proposition sounds perfectly logical.

    Qt::AutoConnection (default) - If the signal is emitted from a different thread than the receiving object, the signal is queued, behaving as Qt::QueuedConnection. Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection. The type of connection is determined when the signal is emitted.

    Qt::QueuedConnection - The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.


Log in to reply