У меня есть два класса: обработчик и рабочий, связанный с сигналом и слотами. Вот это упрощенная версия (псевдо-код):Слоты внутри QThread, работающие одновременно
Обработчик Конструктор:
Handler::Handler(QObject *parent) : QObject(parent)
{
m_workerThread = new QThread;
m_worker = new Worker;
m_worker->moveToThread(m_workerThread);
m_workerThread->start();
connect(this, &Handler::doWork, m_worker, &Worker::doWork);
connect(this, &Handler::stopWork, m_worker, &Worker::stopWork);
emit doWork();
}
работник
void Worker::doWork()
{
qDebug()<<"------"
qDebug()<<"Start do work executing in: "<<QThread::currentThreadId();
//doing some work
m_timer->start();//a singleshot timer that calls doWork() on timeout
qDebug()<<"work done";
qDebug()<<"------"
}
void Worker::stopWork()
{
qDebug()<<"Stop timer executing in: "<<QThread::currentThreadId();
m_timer->stop();
}
Поэтому в основном работают начинается после того, как излучающие "DoWork" из обработчика. Слот «doWork» имеет таймер однократного таймера, который вызывает одну и ту же функцию снова через определенное время. Спустя некоторое время обработчик излучает сигнал «stopWork». Вот мой отладочный вывод:
------
Start do work executing in: 0x65602450
work done
------
------
Start do work executing in: 0x65602450
work done
------
------
Start do work executing in: 0x65602450
work done
------
------
Start do work executing in: 0x65602450
stop work emitted from handler in: 0x750a7000
Stop timer executing in: 0x65602450
work done
------
------
Start do work executing in: 0x65602450
work done
------
etc...
Так что я не понимаю, как это вообще возможно, что мой рабочий поток выполняет два слота (DoWork и stopWork) в то же время? Должен ли сигнал stopWork быть отправлен и ждать, пока поток не станет Idle перед выполнением слота «stopWork»?
К сожалению, я не смог воспроизвести это, используя минимальный рабочий пример, но я надеюсь, что из кода, который я разместил, ясно, что мне не хватает.
Также из моих тестов я понял, что это происходит в 30-40% случаев.
Что происходит в разделе «Выполнение какой-либо работы» в «Worker :: doWork»? Если в любой момент во время этого кода управление возвращается (хотя и ненадолго) в цикл событий, то я думаю, что вполне возможно, что другой запрошенный сигнал начнет обрабатываться. Следовательно, ваши слоты не выполняются параллельно, они фактически вложены. –
Я вызываю некоторые функции, реализованные другими классами. Не могли бы вы привести несколько примеров того, как управление возвращается в цикл событий? Я не могу понять, так ли это в тех функциях, которые я звоню! – luffy
Большое спасибо за подсказку. Ты был прав. Я узнал, что код, который я вызывал, использует «QCoreApplication :: processEvents()» – luffy