Почему мой рабочий работает в неправильном потоке? - PullRequest
1 голос
/ 05 августа 2020

У меня есть класс Messenger с двумя внутренними указателями на объекты:

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

В конструкторе Messenger я создаю эти объекты и назначаю их этим интеллектуальным указателям следующим образом:

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();
}

и внутри моего ReceiverWorker::process() я вызываю

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

Теперь эти два вызова qDebug() выводят разные значения: например:

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

, так что это похоже на ReceiverWorker работает в другом потоке, чем я хочу. Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 05 августа 2020

Он делает именно то, что должен. Термин stdin_receiver_thread_.get()->thread(); дает QThread, в котором stdin_receiver_thread_ живет как QObject. Другими словами, ваш основной поток или где бы то ни было Messenger был создан.

Если бы вы вместо этого просто написали:

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

, вы бы получили ожидаемый результат.

std::unique_ptr<QThread>

Вы не должны использовать std::unique_ptr с QObject, для которого вы звоните deleteLater(). Это неизбежно приводит к повреждению double-free / heap.

2 голосов
/ 05 августа 2020

Вы вызываете QObject :: thread () для объекта QThread. В документах говорится: «Возвращает поток, в котором живет объект». QThread - это объект, который живет в основном потоке. Я думаю, ваша функция работает должным образом, вы просто не сравнивали правильные значения для своих qDebugs.

...