В чем причина статуса ошибки QProcess 5?

у меня есть несколько потоков, выполняющих следующий QProcess. Случайным образом они терпят неудачу с состоянием ошибки 5. Документация Qt не дает более подробной информации. Кто-нибудь знает, от чего может исходить эта ошибка? Большое тебе спасибо.

extCmd = new QProcess(this);

QString cmd = "/usr/bin/php";
QStringList argStr;
argStr << "/bin/sleep" << "10"; // changed to ever working command
extCmd->start(cmd, args);
bool suc = extCmd->waitForFinished(-1);
if (!suc) {
   qDebug() << "finishing failed error=" 
            << extCmd.error() 
            << extCmd.errorString();
}

Дает мне вывод:

finishing failed error= 5 "Unknown error"

person spikey    schedule 29.05.2012    source источник
comment
Код ошибки 5 является кодом ошибки по умолчанию, возможно, процесс, который вы вызываете, дает сбой, а не QProcess?   -  person cmannett85    schedule 29.05.2012
comment
что в cmd и args?   -  person ScarCode    schedule 29.05.2012
comment
Привет, спасибо, что заглянули. Я добавил содержимое команды и параметра.   -  person spikey    schedule 29.05.2012
comment
@ cbamber85 хороший момент для начала: я изменил команду на то, что всегда работает /bin/sleep 10. Теперь я вижу, что параметр waitForFinished() не действует: -1 и 20000 всегда терпят неудачу. Как это может быть?   -  person spikey    schedule 29.05.2012
comment
UPS. Прошу прощения, я сделал ошибку в анализе журнала, только несколько процентов не работают.   -  person spikey    schedule 29.05.2012
comment
@spikey Он все еще не работает с Error 5 или с другим? И, из любопытства, сколько потоков вы запускаете одновременно?   -  person cmannett85    schedule 29.05.2012
comment
не обработал возврат с кодом состояния, отличным от 0?   -  person Kamil Klimek    schedule 29.05.2012
comment
@cbamber85 cbamber85 все еще не работает с ошибкой 5. Я запускаю около 100 потоков. Дополнительное примечание: сейчас я обновился до Qt Libs 4.8.2, потому что прочитал о QProcess в изменениях выпуска, но ошибка осталась. Я получаю дополнительное сообщение: QSocketNotifier: Internal error. :-(   -  person spikey    schedule 29.05.2012
comment
@KamilKlimek extCmd.exitCode() равно 0, а extCmd.state() равно 2 после waitForFinished(-1), если bool suc ложно.   -  person spikey    schedule 29.05.2012
comment
100 тем сразу! Вам следует подумать о том, чтобы поместить их в QThreadPool и ограничить его количеством ядер, но я сомневаюсь, что это имеет какое-либо отношение к вашим проблемам.   -  person cmannett85    schedule 30.05.2012


Ответы (1)


К вашей проблеме имеет отношение тот факт, что вы не должны не запускать поток для каждого процесса. QProcess посылает сигнал finished(int code, QProcess::ExitStatus status), когда это делается. Он также будет выдавать started() и error() при успешном и неудачном запуске соответственно. Подключите все эти три сигнала к слоту в QObject, затем запустите процесс и обработайте результаты в слотах. Вам не понадобятся дополнительные нити.

Если вы получите сигнал started(), то можете быть уверены, что имя файла процесса было правильным, и процесс был запущен. Какой бы код выхода вы ни получили от finished(int), он указывает на то, что сделал процесс, возможно, в ответ на потенциально недопустимые аргументы, которые вы могли ему передать. Если вы получаете сигнал error(), процесс не запустился, потому что вы дали неверное имя файла QProcess::start() или у вас нет правильных разрешений.

Вы не должны писать синхронный код, в котором все происходит асинхронно. Синхронный код — это код, который блокирует выполнение определенных действий, например вызов waitForCmdFinished. Я бы хотел, чтобы был флаг конфигурации Qt, который отключает все эти оставшиеся API-интерфейсы синхронной блокировки, точно так же, как есть флаг для отключения/включения API-интерфейсов поддержки Qt 3. Сама по себе доступность этих блокирующих API способствует совершению ужасных взломов, подобных приведенному выше коду. Эти API должны быть отключены по умолчанию ИМХО. Так же, как должен быть тест на перемещение QThread и производных классов в другой поток. Это также признак плохого дизайна в каждом примере общедоступного кода, который я мог найти, и я провел довольно тщательный поиск, чтобы убедить себя, что я не сумасшедший или что-то в этом роде.

Единственное разумное использование метода waitxxx в Qt, которое я помню, — это ожидание завершения QThread. Даже в этом случае это следует вызывать только из ~QThread, чтобы предотвратить разрушение QThread при работающем протекторе.

person Community    schedule 31.05.2012
comment
Спасибо за ваш ответ, я выбрал его в качестве ответа на свой вопрос, потому что прямого ответа нет. Я пробовал разные подходы. Во-первых, необходимо избегать блокирующего (синхронного) кода при использовании QProcess в многопоточном приложении. Во-вторых, я создал один-единственный поток, который обрабатывал все запросы, обрабатывая очередь независимо от других потоков. - person spikey; 03.08.2012