QProcess: выполнение блокирует все приложение
В моем приложении я использую следующий код для создания новых потоков и выполнения внешнего приложения в этих потоках:
int main(int argc, char *argv[])
{
...
WebSocketServer *server = new WebSocketServer();
QObject::connect(server, &WebSocketServer::closed, &a, &QCoreApplication::quit);
QObject::connect(server, SIGNAL(messageReceived(QJsonObject)), dm, SIGNAL(sendHandleProcessedFiles(QJsonObject)));
QObject::connect(dm,SIGNAL(sendServerNotify(int, QByteArray)),server,SLOT( notifySender(int, QByteArray)));
}
void WebSocketServer::processTextMessage(QString message)
{
QThread* workerThread = new QThread();
Task *task = Task::createTask(Id);
task->moveToThread(workerThread);
QObject::connect(task, SIGNAL(workFinished()), workerThread, SLOT(quit()));
QObject::connect(workerThread, SIGNAL(finished()), task, SLOT(deleteLater()));
QObject::connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
task->execute();
}
void Task::execute()
{
...
//Execute external program
QProcess process;
process->start(cmd);
process->waitForFinished(-1);
//Execution should continue after termination of external program within the thread created in WebSocketServer::processTextMessage
...
}
Внутри объекта моей задачи я должен выполнить внешнюю программу, дождаться окончания ее выполнения и продолжить свой программный код. Я хочу, чтобы мой поток ждал завершения выполнения программы, поэтому никакой асинхронный механизм не нужен.
Проблема заключается в том, что не только отдельный поток ожидает программу, но и весь поток в целом. приложение блокируется до завершения работы программы. Таким образом, все запросы, которые я получаю, например, для моего сервера websocket, блокируются.
Я ожидал, что процесс выполняется в потоке, откуда он вызывается, и не влияет на другие потоки. Есть идеи?
1 ответ:
Насколько я понимаю ваш вопрос, Ваша проблема здесь:
QThread* workerThread = new QThread(); Task *task = Task::createTask(Id); task->moveToThread(workerThread); ... workerThread->start(); task->execute();
Здесь вы выполняете задачу в основном потоке, а не в рабочем потоке. Заметьте, что по
moveToThread
все слоты выполняются в новом потоке, а не явные вызовы методов.В вашем коде
task->execute();
выполняется в основном потоке.