2016-09-20 2 views
2

In meiner Anwendung ich den folgenden Code verwenden, um neue Themen zu erstellen und eine externe Anwendung in dieser Threads ausführen:QProcess: execute Blöcke gesamte Anwendung

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

In meinem Aufgabenobjekt muß ich ein externes Programm ausführen, warten bis die Ausführung beendet ist und meinen Programmcode fortsetzen. Ich möchte, dass mein Thread wartet, bis die Ausführung des Programms beendet wird, so dass kein asynchroner Mechanismus notwendig ist.

Das Problem, das ich habe, ist, dass nicht nur der einzelne Thread auf das Programm wartet, sondern die gesamte Anwendung blockiert ist, bis das Programm beendet wird. So werden alle Anfragen, die ich zum Beispiel für meinen Websocket-Server erhalte, blockiert.

Ich erwartete, dass der Prozess in dem Thread ausgeführt wird, von dem es aufgerufen wird, und die anderen Threads nicht beeinflusst. Irgendwelche Ideen?

+1

Können Sie die 'Task :: createTask'-Implementierung bereitstellen. Außerdem geben Sie nicht genau an, wo/wie 'QProcess :: execute' aufgerufen wird. Mein Verdacht ist, dass 'Task :: createTask' 'QProcess :: execute' * aufruft, bevor * die Aufgabe auf den neuen' QThread' verschoben wird. Nur eine Vermutung. –

+3

Bitte geben Sie ein vollständiges minimales Beispiel an, keine Schnipsel. Der gesamte Code, den Sie zeigen, ist korrekt, die fehlenden Bits sind sehr wichtig, da das Problem dort liegt. –

+1

Wahrscheinlich starten Sie den Thread im Konstruktor des Worker-Objekts. Stattdessen sollten Sie es aufschieben, bis das Objekt bereit ist zu verwenden - d. H. Sie sollten es aus der Ereignisschleife auslösen, indem Sie einen Nullzeit-Timer verwenden, um einen 'init'-Slot/Funktor auszuführen. –

Antwort

2

Soweit ich verstehe Ihre Frage, Ihr Problem ist hier:

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

Hier sind Sie die Aufgabe in dem Haupt-Thread nicht in diesem Worker-Thread ausgeführt wird. Beachten Sie, dass durch moveToThread alle Slots im neuen Thread ausgeführt werden, keine expliziten Methodenaufrufe. In Ihrem Code wird task->execute(); im Hauptthread ausgeführt.

+0

Das wusste ich nicht. Wie kann ich es in dem Thread ausführen, den ich hier erstellt habe? – HansHupe

+1

@HansHupe Ein schönes Tutorial wäre [diese Seite] (http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/). –

+0

@HansHupe Gefällt mir [this] (http://Stackoverflow.com/a/21653558/1329652) :) –