Search code examples
c++multithreadingqtsignals-slotsqt-signals

Qt: Sending signal to dead/stopped thread


I've come across the problem, that I might be sending signals from one QThread to another, however I have no way of checking if the thread that is implementing the slot is running. How will the framework handle such a situation while using Qt::QueuedConnection ?

...
WorkerImp* pWorker = new WorkerImp();
QThread worker;
pWorker->moveToThread(&worker);

QObject::connect(&worker, QThread::finished, pWorker, &QObject::deleteLater, Qt::QueuedConnection);
bool connected = QObject::connect(this, &SlaveMaster::requireWork, pWorker, &WorkerImp::doWork, Qt::QueuedConnection);
assert(connected);

// at this point we have connected the signal, thread is not starded.
// however the object that we use to connect still exists and will after we exit the thread.


worker.start();
worker.exit();
worker.wait();

// note that when we exit the QThread we do not destroy the object - it can be start over

emit requireWork();
...

Solution

  • The signal is never handled. A queued connection across threads is posted as an event to the thread, handled by its event loop. If the thread is stopped (and thus its event loop), there is no one to pick up the event and deliver it:

    From the Qt Docs Signals and Slots Across Threads:

    Queued Connection: 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.

    and Per-Thread Event Loop:

    [...] If no event loop is running, events won't be delivered to the object.

    Note that a blocking queued connection would dead-lock