У меня есть операция без графического интерфейса, которую я собираюсь выполнить в рабочем потоке. Погуглив, я нашел простой способ добиться этого здесь
В частности, QMetaObject::invokeMethod()
меня вполне устраивает. Я также позаботился о том, чтобы не создавать подклассы QThread, а вместо этого создавать подклассы QObject для создания моего рабочего объекта, а затем перемещать привязку потока этого объекта к вновь созданному потоку. (подробно описано здесь
Теперь мой вопрос:
Я начну ставить методы в очередь из своего основного потока (предполагаю, что это происходит под капотом с помощью QEventLoop, хотя я его не устанавливал и не переустанавливал QThread::run()
и не вызывал QThread::exec()
). Мне нужно выяснить, когда мой рабочий закончил обработку. Другими словами, мне нужно знать, когда QEventLoop пуст. Я подумал, что могу использовать для этого сигнал finish(). Но это не работает. Может ли кто-нибудь пролить свет на то, как узнать, когда рабочий поток завершил выполнение? Если вам нужна дополнительная информация/код, просто дайте мне знать.
Плагин класса является подклассом QObject.
Plugin::Plugin()
{
m_workerThread = new QThread(this);
m_workerThread->start(QThread::IdlePriority);
m_worker = new DataWorker(this);
connect(m_workerThread, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
m_worker->moveToThread(m_workerThread);
}
...
Plugin::updateData()
{
....
if( true == QMetaObject::invokeMethod(m_worker, "RunFProcToGetData", Qt::QueuedConnection, Q_ARG(QString, foo)))
{
qDebug() << "successfully invoked RunFProcToGetData";
}
if( true == QMetaObject::invokeMethod(m_worker, "updateDataIntoDB", Qt::QueuedConnection, Q_ARG(QSqlDatabase, db), Q_ARG(QString, foo)))
{
qDebug() << "successfully invoked updateDataIntoDB";
}
....
}
В классе Dataworker
Dataworker::RunProcToGetData(const QString &foo)
{
// invoke a program to get the Data
}
Dataworker::updateDataIntoDB(const QSqlDatabase& db, const QString &foo)
{
// Update database
}
Поэтому, когда больше не осталось updateDataIntoDB и RunFPrcToGetData для обработки, мне нужен триггер
quit()
в потоке сигналterminated()
? Если, конечно, вы не хотите, чтобы рабочий постоянно оставался живым, в этом случае вам придется создать свой собственный сигнал. - person cmannett85   schedule 05.11.2012quit()
. - person cmannett85   schedule 05.11.2012m_worker = new DataWorker(this);
.Removethis
.movethread() завершится ошибкой, если установлен родитель. - person UmNyobe   schedule 05.11.2012m_worker.foo();
, в то время как из-за слота другой поток выполняетm_worker.bar
: условия гонки. - person UmNyobe   schedule 05.11.2012