Название: QProcess и QThread Отправлено: Базиля от Ноябрь 30, 2013, 02:37 Здравствуйте!
Назрела проблема, уже даже и не знаю что поделать :( Имеется n потоков. В каждом из которых на запуск подается определенный список исполняемых файлов. Происходит ввод какой-либо информации и собственно ожидание ответа от процесса (мне заранее известно поведение процесса, т.е. после ввода информации - должен произойти вывод и процесс должен завершиться). Код: ... Т.е. предположим у меня сейчас имеется 10 потоков, следовательно у меня есть 10 процессов, которые выполняют одинаковую задачу (проще говоря, на каждый поток свой процесс). И проблема вся в том, что не все процессы одинаково исполняются. К примеру, в 7 потоках из 10, процессы завершились успешно, а вот предположим, что в 8 процессе, выполнилась ветка условия: Код:
Код: if ( !process.waitForBytesWritten( time ) ) { Код:
В процессе тестирования блока, выводил значение времени исполнения данного блока (у меня есть таймер, который и замеряет время). По времени исполнения, ни одно из условий не было истинным (т.е. ни одна из операций не превышала своего заданного времени выполнения). Значит ошибка кроется в чем-то другом, но вот в чем, понять все никак не могу. Ведь процессы одинаковые и в 7 из 10 они были выполнены верно, а в остальных нет. Также хотелось бы отметить, что результаты разнятся, т.е. каждый раз я получаю разный результат выполнения процессов. Подскажите пожалуйста, с чем может быть связана данная проблема. Спасибо! :) Название: Re: QProcess и QThread Отправлено: Igors от Ноябрь 30, 2013, 10:46 Т.е. предположим у меня сейчас имеется 10 потоков, следовательно у меня есть 10 процессов, которые выполняют одинаковую задачу (проще говоря, на каждый поток свой процесс). Это несложно проверить утилитами ОСИ проблема вся в том, что не все процессы одинаково исполняются. Это само по себе нормально, и да, это невоспроизводимо при каждом запуске. Неясно зачем нужно 10 потоков, может лучше сделать все в одном, который запускает 10 процессов и сканирует готовность в цикле. Для начала можно попробовать такКод Возможно просто процесс был вытеснен и нужно больше ждать Название: Re: QProcess и QThread Отправлено: Old от Ноябрь 30, 2013, 11:25 запускает 10 процессов и сканирует готовность в цикле. Для чего это делать в цикле, когда QProcess умеет отсылать сигналы на каждый чих?Название: Re: QProcess и QThread Отправлено: Igors от Ноябрь 30, 2013, 12:38 Для чего это делать в цикле, когда QProcess умеет отсылать сигналы на каждый чих? Ах как Вы бдительны! :) Я имел ввиду незачем делать 10 ниток только для запуска. Можно легко избежать как асинхронно, так и синхронно (что тоже неплохо) Название: Re: QProcess и QThread Отправлено: Базиля от Ноябрь 30, 2013, 13:06 Благодарю за ответы! :)
Это несложно проверить утилитами ОС Я через тесты удостоверился, что у каждого потока свой процесс.В этом плане проблем нет. Это само по себе нормально, и да, это невоспроизводимо при каждом запуске. Неясно зачем нужно 10 потоков, может лучше сделать все в одном, который запускает 10 процессов и сканирует готовность в цикле. Для начала можно попробовать так 10 потоков - потому что в дальнейшем будут разные процессы.Код Возможно просто процесс был вытеснен и нужно больше ждать У каждого потока будет задача - запуск процесса, ввод данных, считывание ответа и все в том же духе. Сейчас у меня идет тестирование модуля и для удобства я у меня все процессы одинаковые. Насчет вытеснения процесса - идея хорошая, спасибо. Но в таком случае, таймер бы показал, что метод waitForBytesWritten (к примеру) превысил время выполнения в сравнении с переменной time. А мой лог показывает обратное - время выполнения в среднем не превышает и 100 мс. Когда в качестве параметра я передаю 2 секунды :( Спасибо! Название: Re: QProcess и QThread Отправлено: Old от Ноябрь 30, 2013, 13:29 Ах как Вы бдительны! :) Я имел ввиду незачем делать 10 ниток только для запуска. Можно легко избежать как асинхронно, так и синхронно (что тоже неплохо) Если бы вы хотели сказать только это, то не привели бы этот бесполезный кусок кода. ;)Ну да ладно. В процессе тестирования блока, выводил значение времени исполнения данного блока (у меня есть таймер, который и замеряет время). Если возникает ошибка, то никто указанный интервал ждать не будет. Функция сразу завершиться. А вот почему происходят ошибки нужно разбираться. Причем странно, что ошибки могут возникать на разных этапах выполнения.По времени исполнения, ни одно из условий не было истинным (т.е. ни одна из операций не превышала своего заданного времени выполнения). Название: Re: QProcess и QThread Отправлено: Базиля от Ноябрь 30, 2013, 20:47 Если возникает ошибка, то никто указанный интервал ждать не будет. Функция сразу завершиться. А вот почему происходят ошибки нужно разбираться. Причем странно, что ошибки могут возникать на разных этапах выполнения. Я просто лишний раз хотел сказать, что дело не в тайм ауте :)По поводу ошибки, кстати, самое интересное, что errorString() выводит "Unknown error". Название: Re: QProcess и QThread Отправлено: Old от Ноябрь 30, 2013, 22:03 Я просто лишний раз хотел сказать, что дело не в тайм ауте :) Тогда нужно не время засекать, а пытаться понять, что происходит не так.К примеру, в 7 потоках из 10, процессы завершились успешно, а вот предположим, что в 8 процессе, выполнилась ветка условия: Что значит предположим/допустим? Эти ситуации происходят на самом деле или вы пытаетесь продумать, как нужно на них реагировать?... Или в 9 допустим : ... Ну и в 10, предположим : Название: Re: QProcess и QThread Отправлено: Igors от Декабрь 01, 2013, 10:58 Есть смысл заняться запускаемым - заменить его на что-то совсем простое типа "мама мыла раму" и откатать на нем
Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 01, 2013, 19:45 Тогда нужно не время засекать, а пытаться понять, что происходит не так. Я время засекал, чтобы убедиться, что проблема не в тайм ауте :)Что значит предположим/допустим? Эти ситуации происходят на самом деле или вы пытаетесь продумать, как нужно на них реагировать? Эти ситуации происходят на самом деле, просто в хаотичном порядке.Сейчас, предположим, если запустить - все процессы выполнятся удачно, а при следующем запуске - 2 из 10 пройдут по ветке одного из условий. Есть смысл заняться запускаемым - заменить его на что-то совсем простое типа "мама мыла раму" и откатать на нем А запускаемый процесс сейчас проще некуда - на вход подается число, а на выходе квадрат этого числа :)Сейчас решил немного упростить тестирование, используя только 1 поток - запускаю подряд 500 раз один и тот же процесс. Результаты такие же, на какой-нибудь из попыток запуска (каждый раз ее номер отличается) процесс проходит по ветке одного из условий. То есть сам факт того, что один и тот же процесс не может быть выполнен одинаково 500 раз подряд меня вводит в заблуждение :( Благодарю! Название: Re: QProcess и QThread Отправлено: Igors от Декабрь 01, 2013, 19:55 Заинтриговали :) Выкладывайте минимальные исходники, на неделе найду время и попытаюсь разобраться
Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 01, 2013, 20:29 Спасибо! :)
Если прямо в посте код скину, удобно будет? Название: Re: QProcess и QThread Отправлено: Old от Декабрь 01, 2013, 23:09 Спасибо! :) Нет. Лучше архив со всеми файлами включая .pro.Если прямо в посте код скину, удобно будет? Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 02, 2013, 21:43 Вынес функцию отдельно, убрал логи - дабы не путать :)
Заранее благодарю! :) Название: Re: QProcess и QThread Отправлено: Old от Декабрь 02, 2013, 22:41 Вынес функцию отдельно, убрал логи - дабы не путать :) А что там в 1.exe? Похоже что дело в нем.У меня нет венды, поэтому я заменил 1.exe на shell-скрипт, который читает из канала и записывает в канал 4. Несколько раз запускал, всегда выполняется 1000 раз без ошибок. Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 03, 2013, 05:56 Хммм, интересно :)
А там простая программка, которой на вход подается число, а на выходе квадрат этого числа. Название: Re: QProcess и QThread Отправлено: Igors от Декабрь 04, 2013, 10:09 Я на OSX и воспользоваться 1.exe не смог, сделал такое консольное приложение
Код Ну отрабатывает все 1000 раз, ошибок нет. Немного покрутил Ваш исходник (на всякий случай прилагаю) - результат тот же, ошибок нет Название: Re: QProcess и QThread Отправлено: CuteBunny от Декабрь 04, 2013, 17:23 У меня 1.exe не запустился - это хорошо или плохо? :'(
Как его 1.exe использовать? Там число через argc, argv? А на чем написано? Исходный код 1.exe в студию! Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 04, 2013, 23:20 Спасибо за ответы! :)
Я на OSX и воспользоваться 1.exe не смог, сделал такое консольное приложение Благодарю!Код Ну отрабатывает все 1000 раз, ошибок нет. Немного покрутил Ваш исходник (на всякий случай прилагаю) - результат тот же, ошибок нет Учту ваши изменения, все никак не могу избавиться от "магических чисел", пора лупить себя по рукам :) Что же тогда делать, ума не приложу. Попробую тогда на другой ОС запустить (текущая XP), посмотрим что выйдет, глупо конечно на это надеяться, проблема явно в другом, но других идей нет :( У меня 1.exe не запустился - это хорошо или плохо? :'( Странно, что не запускается.Как его 1.exe использовать? Там число через argc, argv? А на чем написано? Исходный код 1.exe в студию! Вот сам код Код: #include <iostream> Название: Re: QProcess и QThread Отправлено: Old от Декабрь 05, 2013, 09:23 Что же тогда делать, ума не приложу. Скажите, а у вас установлен антивирус?Попробуйте его отключить на время теста. А делать нужно будет следующее: правильно обрабатывать ошибки и перезапускать процессы завершившиеся с ошибкой. Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 06, 2013, 00:34 Скажите, а у вас установлен антивирус? Насчет антивируса уже приходила мысль :)Попробуйте его отключить на время теста. А делать нужно будет следующее: правильно обрабатывать ошибки и перезапускать процессы завершившиеся с ошибкой. Отключал - бесполезно :( Скорее всего так и придется поступать. Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 08, 2013, 14:46 Господа, проверил я это все дело на Ubuntu.
И как ни странно, но все прекрасно работает! :) Спасибо огромное всем отозвавшимся! Теперь уже проблема ясна - нюансы были в ОС , нет ни у кого случайно предположений на этот счет? Хотелось бы просто дальше продолжать писать на родном XP ;D Спасибо! Название: Re: QProcess и QThread Отправлено: Igors от Декабрь 08, 2013, 14:57 Теперь уже проблема ясна - нюансы были в ОС , нет ни у кого случайно предположений на этот счет? Так это нырять болото Вындоуз :) Для начала перебрать 1.exe c multi-threaded (DLL), да и с Debug и без - там это запросто может быть по-разному. Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 08, 2013, 16:22 Для начала перебрать 1.exe c multi-threaded (DLL), да и с Debug и без - там это запросто может быть по-разному. Думаете что проблема все-таки в exe файле?Название: Re: QProcess и QThread Отправлено: ViTech от Декабрь 09, 2013, 13:23 У меня 1.exe не запустился - это хорошо или плохо? :'( Странно, что не запускается.Как его 1.exe использовать? Там число через argc, argv? А на чем написано? Исходный код 1.exe в студию! Не странно. libgcc_s_dw2-1.dll и libstdc++-6.dll не в каждой винде есть :). Если хотите, чтоб тестировали именно этот 1.exe, соберите его со стандартными виндовыми библиотеками. Попробуйте поставить задержку после запуска процесса, например: Код: process.start( fileExe ); Код: if ( !process.waitForStarted() ) { Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 10, 2013, 23:06 Не странно. libgcc_s_dw2-1.dll и libstdc++-6.dll не в каждой винде есть :). Если хотите, чтоб тестировали именно этот 1.exe, соберите его со стандартными виндовыми библиотеками. Попробуйте поставить задержку после запуска процесса, например: Но документация говорит об обратном:Код: process.start( fileExe ); Код: if ( !process.waitForStarted() ) { Цитировать bool QProcess::waitForStarted(int msecs = 30000) ???Blocks until the process has started and the started() signal has been emitted, or until msecs milliseconds have passed. Returns true if the process was started successfully; otherwise returns false (if the operation timed out or if an error occurred). Я в тестах отслеживал статус процесса - ни разу не было такой ситуации, чтобы я начинал запись в не запущенный процесс. P.S. Ради интереса решил попробовать - ничего не изменилось( В общем к чему я пришел. Если убрать строчку кода: Код: if ( !process.waitForBytesWritten( time ) ) { Ошибок пока что нет. Но стоит оставить этот if, как на каком-нибудь из процессов функция обязательно вернет false. В документации говорится, что это возможно только в 2-ух случаях: Цитировать Returns true if a payload of data was written to the device; otherwise returns false (i.e. if the operation timed out, or if an error occurred). Тайм аут - исключено.Насчет ошибки - тоже. Ибо функция process.errorString() возвращает unknwon error. А сигнал error даже не испускается. Единственное, что я обнаружил - в тех случаях когда эта функция возвращает false, перед проверкой этого условия, процесс закрылся, т.е. его статус с 2 сменился на 0: Цитировать 0 - The process is not running. Почему это так происходит, не понятно.1 - The process is starting, but the program has not yet been invoked. 2 - The process is running and is ready for reading and writing. По логике вещей - убрав эту злосчастную проверку, ситуация должна была бы повториться - на проверке следующего условия Код: if ( !process.waitForReadyRead( time ) ) { Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 11, 2013, 00:25 Прошу прощения, я кажется разобрался с проблемой ;D ;D ;D
Я просто немного идиот :) Для тестирования выбрал не совсем удачный процесс. После ввода информации в процесс, он успевал сразу завершаться, прежде чем я попытаюсь проверить - удачно ли записалась в него информация или готов ли вообще процесс к считывания с него байтов. Функция естественно возвращал false - т.к. на момент проверки процесс уже был завершен. Просто мне везло в ряде тестов и процесс успевал не завершаться до проверки этих условий. Это меня и вводило в заблуждение. Я уже просто голову себе сломал, начал рыть не в том месте яму, а проблема оказалась совершенно в другом :) Как я понял здесь только один вариант - добавить дополнительное условие на текущую активность процесса. Я прав? P.S. И сразу такой вопрос назрел - если процесс завершился, а я программно не успел считать с него данные, они пропадут? В моем текущем коде, это ведь возможно. Или может в QProcess есть буфер, в который помещается информация из выходного потока процесса? Судя по всему он есть, ведь у меня считывались откуда то данные после завершения процесса. Я подозреваю, что лучше тогда просто ловить сигнал readyRead. Название: Re: QProcess и QThread Отправлено: Majestio от Декабрь 11, 2013, 08:52 P.S. И сразу такой вопрос назрел - если процесс завершился, а я программно не успел считать с него данные, они пропадут? Попробуйте запускать процесс немного по другому. Вот пример, где слот запускает внешний процесс, записывает данные в STDIN этого процесса, ожидает завершения, читает STDOUT процесса: Код: void MainWindow::SlotRun() Сделал "процесс" отрабатывающим достаточно быстро: StartHidden.cmd Код: sort Код: Название: Re: QProcess и QThread Отправлено: ViTech от Декабрь 11, 2013, 12:03 Но документация говорит об обратном: В документации написано, как метод должен работать в общем случае, на всех платформах, при удачном расположении планет :). Но истина всегда в исходниках. В частности, для виндовс можно увидеть следующее:Цитировать bool QProcess::waitForStarted(int msecs = 30000) ???Blocks until the process has started and the started() signal has been emitted, or until msecs milliseconds have passed. Returns true if the process was started successfully; otherwise returns false (if the operation timed out or if an error occurred). Я в тестах отслеживал статус процесса - ни разу не было такой ситуации, чтобы я начинал запись в не запущенный процесс. Код Между функцией CreateProcess и установкой статуса процесса в QProcess::Running нет никаких ожиданий. В конце метода только строка Код в версии 4.8, которую в 5-ой уже убрали. Это метод QProcessPrivate::startProcess() в <Qt>\src\corelib\io\qprocess_win.cpp. В этом файле можно посмотреть всю работу с процессами в винде. Для линукса поведение отличается, и там, на сколько я понял, есть какое-то ожидание(подтверждение) при запуске процесса. К тому же, какой момент времени считать, что процесс "запустился"? 1. Завершилась системная функция запуска процесса. 2. Создались и готовы к работе каналы ввода/вывода. 3. Запустился главный(первый) поток процесса. 4. Создался и проинициализировался основной объект процесса. 5. Создалось главное окно приложения. 6. Главное окно отобразилось на экране. 7. ... Какого момента в программе надо дождаться, чтобы считать процесс запущенным? И кто такой момент сможет сообщить? :) Так что нет никакой магии, и статус QProcess::Running еще ничего не гарантирует. Работа с каналами ввода/вывода тоже может не одинаково выполняться в разных ОС. Тут только плотное тестирование поможет :). Название: Re: QProcess и QThread Отправлено: Базиля от Декабрь 19, 2013, 17:12 Извините, что пропал.
ViTech Majestio Спасибо Вам за информацию! ViTech Если я все правильно понял, возможна ли такая ситуация, когда я могу попытаться записать какую-то информацию в еще не запущенный процесс? Как тогда лучше всего определять время ожидания для запуска процесса? Ведь сейчас нам может понадобиться около 200 мс, а при следующем запуске, к примеру, все 300 мс. И как тогда в таком случае сам QProcess поймет, что процесс еще не запущен, если статус не гарантирует текущее состояние процесса? Название: Re: QProcess и QThread Отправлено: ViTech от Декабрь 20, 2013, 12:19 Если я все правильно понял, возможна ли такая ситуация, когда я могу попытаться записать какую-то информацию в еще не запущенный процесс? Возможна ситуация, когда процесс еще не дошел до необходимой стадии "запущенности" :). Хотя QProcess, по своей функциональности, должен обеспечивать наличие работающих каналов ввода/вывода для запущенного процесса (но не факт, что процесс сразу начнет отвечать). Так что в вашем случае все должно работать. Нужно разбираться, как происходит работа с каналами. Сохранять отладочные сообщения каждого действия с точным временем в файл в обоих процессах. Но надо учитывать, что запись в файл занимает достаточно много времени, и если это потом убрать, то все опять может поломаться :).Как тогда лучше всего определять время ожидания для запуска процесса? Конкретное время в мс лучше никак не определять, все равно не угадаешь :). Никто, кроме самого процесса, не сможет сообщить, какой стадии запуска он достиг. Нужно синхронизироваться с ним каким-нибудь из способов межпроцессного взаимодействия. В простом случае с QProcess каналов ввода/вывода должно хватить, в сложных - зависит от ситуации и потребностей.Ведь сейчас нам может понадобиться около 200 мс, а при следующем запуске, к примеру, все 300 мс. |