2

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?

HansHupe
  • 476
  • 3
  • 13
  • 1
    Can you provide the `Task::createTask` implementation. Also, you don't specify exactly where/how `QProcess::execute` is invoked. My suspicion is that `Task::createTask` is invoking `QProcess::execute` *before* the task is moved to the new `QThread`. Just a guess though. – G.M. Sep 20 '16 at 16:57
  • 3
    Please provide a complete minimal example, not snippets. All the code you show is correct, the missing bits are super-important since that's where the problem actually is. – Kuba hasn't forgotten Monica Sep 20 '16 at 17:11
  • 1
    Most likely you're starting the thread inside the worker object's constructor. Instead, you should defer it until the object is ready to use - i.e. you should fire it off the event loop, by using a zero-duration timer to execute an `init` slot/functor. – Kuba hasn't forgotten Monica Sep 20 '16 at 17:12
  • 1
    Finally, there's no point whatsoever to moving a `QProcess` instance to a different thread, unless you do some heavy computation/communication with the process. Most likely you simply want to be notified when the process is done: for that, you should *never* use a `waitFor` method; instead connect to the `finished` signal. Your code will run when it's time for it to run. – Kuba hasn't forgotten Monica Sep 20 '16 at 17:14
  • 1
    This question is most likely a duplicate of [this question](http://stackoverflow.com/q/10777147/1329652). Seeing a `QProcess` and `QThread` in the same question usually smells bad. – Kuba hasn't forgotten Monica Sep 20 '16 at 17:15
  • Thanks for your comments. I added some code hope it helps to describe the problem a bit better. – HansHupe Sep 20 '16 at 19:15

1 Answers1

2

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.

frogatto
  • 28,539
  • 11
  • 83
  • 129