Search code examples
c++qtqthread

Why is my worker working in a wrong thread?


I have a class Messenger with two internal object pointers:

    std::unique_ptr<QThread> stdin_receiver_thread_ = nullptr;
    std::unique_ptr<ReceiverWorker> stdin_receiver_ = nullptr;

In the constructor of the Messenger I create these objects and assign them to these smart pointers like so:

Messenger::Messenger(QObject *parent) : QObject(parent) {

    // create the objects
    stdin_receiver_thread_ = std::make_unique<QThread>(); 
    stdin_receiver_ = std::make_unique<ReceiverWorker>();
    //
    qDebug() << "stdin_receiver_thread_:" << stdin_receiver_thread_.get()->thread();

    // I assign the worker to this the newly created thread
    stdin_receiver_->moveToThread(stdin_receiver_thread_.get());
    //

    connect(stdin_receiver_thread_.get(), &QThread::started, stdin_receiver_.get(), &ReceiverWorker::process);
    connect(stdin_receiver_.get(), &ReceiverWorker::receivedMessage, stdin_receiver_thread_.get(), &QThread::quit);
    connect(stdin_receiver_.get(), &ReceiverWorker::receivedMessage, stdin_receiver_.get(), &QObject::deleteLater);
    connect(stdin_receiver_thread_.get(), &QThread::finished, stdin_receiver_thread_.get(), &QObject::deleteLater);

    stdin_receiver_thread_->start();
}

and inside my ReceiverWorker::process() i call

qDebug() << "Receiverworker currentThread:" << QThread::currentThread();

Now, those two qDebug() calls print different values: i.e.:

stdin_receiver_thread_: QThread(0x20a24e57ba0)
Receiverworker currentThread: QThread(0x20a2e6f58e0)

so it's like ReceiverWorker works in some different thread than I want it to. What am I doing wrong?


Solution

  • It's doing exactly what it should. The term stdin_receiver_thread_.get()->thread(); yields the QThread in which stdin_receiver_thread_ as a QObject lives. In other terms your main thread or wherever Messenger was constructed.

    If you had instead just written:

    qDebug() << "stdin_receiver_thread_:" << stdin_receiver_thread_.get();
    

    you would have gotten the expected output.


    std::unique_ptr<QThread>
    

    You should not be using std::unique_ptr with a QObject for which you call deleteLater(). That inevitably results in a double-free / heap corruption.