HansHupe HansHupe - 2 months ago 26
C++ Question

QProcess:execute blocks entire application

In my application I use the following code to create new threads and execute an external application in those threads:

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
...
}


Inside my task object I have to execute an external program, wait until its execution finishes and continue my program code. I want that my thread waits until the execution of the program terminates, so no asynchronous mechanism is necessary.

The problem I have is that not only the individual thread waits for the program, but the entire application is blocked until the program terminates. So all requests i receive for example for my websocket server are blocked.

I expected that the process is executed in the thread from where it's called and doesn't effect the other threads. Any ideas?

Answer

As far as I understand your question, your problem is here:

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

Here, you're executing the task in the main thread not in that worker thread. Note that by moveToThread all slots are executed in the new thread, not explicit method calls.

In your code, task->execute(); is executed in the main thread.

Comments