2016-09-20 3 views
2

В моем приложении я использую следующий код для создания новых потоков и выполнить внешнее приложение в этих потоках: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

Можете ли вы предоставить реализацию 'Task :: createTask'. Кроме того, вы не указываете точно, где/как вызывается 'QProcess :: execute'. Мое подозрение заключается в том, что 'Task :: createTask' вызывает' QProcess :: execute' * до того, как * задача перенесена в новый 'QThread'. Впрочем, догадка. –

+3

Просьба представить полный минимальный пример, а не фрагменты. Весь код, который вы показываете, верен, недостающие бит являются очень важными, так как на самом деле проблема на самом деле. –

+1

Скорее всего, вы начинаете поток внутри конструктора рабочего объекта. Вместо этого вы должны отложить его до тех пор, пока объект не будет готов к использованию, т. Е. Вы должны отключить его от цикла событий, используя таймер с нулевой продолжительностью для выполнения «init' slot/functor. –

ответ

2

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

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

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

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

+0

Я этого не знал. Как я могу выполнить его в потоке, который я создал здесь? – HansHupe

+1

@HansHupe Хороший учебник будет [эта страница] (http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/). –

+0

@HansHupe Like [this] (http://stackoverflow.com/a/21653558/1329652) :) –

Смежные вопросы