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 2

1 ответ:

Насколько я понимаю ваш вопрос, Ваша проблема здесь:

QThread* workerThread = new QThread();
Task *task = Task::createTask(Id);
task->moveToThread(workerThread);
...
workerThread->start();
task->execute();

Здесь вы выполняете задачу в основном потоке, а не в рабочем потоке. Заметьте, что по moveToThread все слоты выполняются в новом потоке, а не явные вызовы методов.

В вашем коде task->execute(); выполняется в основном потоке.