LINUX.ORG.RU

Про qthread moveToThread

 ,


1

2

Возможно ли создавать воркер прямо уже в созданном и qthread или я хочу слишком многого?

Например сейчас создаю поток и рабочий объект в нем так:

    m_eThread = new QThread();
    m_eWorker = new Extractor();
    m_eWorker->moveToThread(m_eThread);

    connect(m_eWorker, &Extractor::errorString, this, &U::errorString);

    connect(m_eWorker, &Extractor::extractionFinished, m_eThread, &QThread::quit);
    connect(m_eWorker, &Extractor::extractionFinished, m_eWorker, &Extractor::deleteLater);
    connect(m_eThread, &QThread::finished, m_eThread, &QThread::deleteLater);

    connect(m_eWorker, &Extractor::initialized, m_eWorker, &Extractor::extract);
    connect(m_eThread, &QThread::started, m_eWorker, [this, fileName, destDir]() {
        QMetaObject::invokeMethod(m_eWorker, [this, fileName, destDir]() { m_eWorker->initialize(fileName, destDir); });
    });

    m_eThread->start();
    m_eThread->setPriority(QThread::LowPriority);

Наркоманская магия (не уверен что последний connect правильно написан) в двух последних connect нужна чтобы Extractor создавал свои обьекты уже будучи перемещенным в m_eThread.
Выделение всего в конструкторе Extractor же приведет что moveToThread сломает, например, QNetworkAccessManager.

Напичкав код qDebug() << __FUNCTION__ << thread(); можно увидить:

U::createExtractionThread QThread(0x229d1b66cf0)
Extractor::Extractor QThread(0x229d1b66cf0)
Extractor::initialize QThread(0x229d5552870)
Extractor::extract QThread(0x229d5552870)
Extractor::extractDir QThread(0x229d5552870)
Extractor::extractFile QThread(0x229d5552870)
★★★★★

Хотя даже start не нужен, так как у меня нет никакого виртуального run.

bhfq ★★★★★
() автор топика

Ты используешь потоки самым неудобным путем. Создай один объект от QObject и помести его в поток. А уже внутри него создавай всё дочернее, управляй сигналами из другого потока

I-Love-Microsoft ★★★★★
()

Что мешает последние два connect записать так?

connect(m_eThread, &QThread::started, m_eWorker, [this, fileName, destDir]() {
    m_eWorker->initialize(fileName, destDir);
    m_eWorker->extract();
});

QThread::started() же обрабатывается объектом в новом потоке, а значит код обработчика будет выполнятся уже в нём.

xaizek ★★★★★
()
Ответ на: комментарий от bhfq

Хотя даже start не нужен, так как у меня нет никакого виртуального run.

Так без start() поток не начнёт исполняться (и не будет emit started()).

xaizek ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Ты предлагаешь один поток в котором объект типа controller который в свою очередь создает нужные объекты «тяжелого» рабочего кода прямо в себе как приватные работая с родителем извне типа сигналами слотами?

bhfq ★★★★★
() автор топика
Ответ на: комментарий от xaizek

start все таки нужен, без него к тому же setPriority(QThread::LowPriority); не работает.

bhfq ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Нельзя вот так просто брать и создавать треды налево и направо. Там у Майи расписано вообще как оно работает, а не то что это истина последней инстанции и прям вот так надо делать в своем приложении.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Код ТС-а глянул, мне показалось что именно так, и перекрестился

I-Love-Microsoft ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.