Russian Qt Forum
Ноябрь 26, 2024, 19:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QProcess и QThread  (Прочитано 13553 раз)
Базиля
Гость
« : Ноябрь 30, 2013, 02:37 »

Здравствуйте!

Назрела проблема, уже даже и не знаю что поделать  Грустный
Имеется n потоков.
В каждом из которых на запуск подается определенный список исполняемых файлов.
Происходит ввод какой-либо информации и собственно ожидание ответа от процесса (мне заранее известно поведение процесса, т.е. после ввода информации - должен произойти вывод и процесс должен завершиться).


Код:
    ...
    process.start( exeFile );
    process.waitForStarted();
    process.write( str.c_str() );

    if ( !process.waitForBytesWritten( time ) ) {
        //Ошибка, данные не были записаны в установленное время
         return;
    }

    if ( !process.waitForReadyRead( time ) ) {
        //Ошибка, данные не были получены в установленное время
        return;
    }

    QByteArray byteArr = process.readAll();

    if ( !process.waitForFinished( time ) ) {
        //Ошибка, программа не была завершена в установленное время
         return;
    }

    //Ура! Процесс завершился корректно, теперь можем заниматься обработкой полученных данных от процесса.
    ...
Самое интересно это то, что процессы у всех потоков исполняются одинаковые.
Т.е. предположим у меня сейчас имеется 10 потоков, следовательно у меня есть 10 процессов, которые выполняют одинаковую задачу (проще говоря, на каждый поток свой процесс).
И проблема вся в том, что не все процессы одинаково исполняются.
К примеру, в 7 потоках из 10, процессы завершились успешно, а вот предположим, что в 8 процессе, выполнилась ветка условия:
Код:
 
    if ( !process.waitForFinished( time ) ) {
        //Ошибка, программа не была завершена в установленное время
          return;
    }
Или в 9 допустим :
Код:
    if ( !process.waitForBytesWritten( time ) ) {
        //Ошибка, данные не были записаны в установленное время
         return;
    }
Ну и в 10, предположим :
Код:
 
    if ( !process.waitForFinished( time ) ) {
        //Ошибка, программа не была завершена в установленное время
         return;
    }

В процессе тестирования блока, выводил значение времени исполнения данного блока (у меня есть таймер, который и замеряет время).
По времени исполнения, ни одно из условий не было истинным (т.е. ни одна из операций не превышала своего заданного времени выполнения).
Значит ошибка кроется в чем-то другом, но вот в чем, понять все никак не могу. Ведь процессы одинаковые и в 7 из 10 они были выполнены верно, а в остальных нет.
Также хотелось бы отметить, что результаты разнятся, т.е. каждый раз я получаю разный результат выполнения процессов.

Подскажите пожалуйста, с чем может быть связана данная проблема.
Спасибо!  Улыбающийся
« Последнее редактирование: Ноябрь 30, 2013, 02:39 от Базиля » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Ноябрь 30, 2013, 10:46 »

Т.е. предположим у меня сейчас имеется 10 потоков, следовательно у меня есть 10 процессов, которые выполняют одинаковую задачу (проще говоря, на каждый поток свой процесс).
Это несложно проверить утилитами ОС

И проблема вся в том, что не все процессы одинаково исполняются.
Это само по себе нормально, и да, это невоспроизводимо при каждом запуске. Неясно зачем нужно 10 потоков, может лучше сделать все в одном, который запускает 10 процессов и сканирует готовность в цикле. Для начала можно попробовать так
Код
C++ (Qt)
int i;
for (i = 0; i < 100; ++i)
 if (process.waitForBytesWritten(time)) break;
 printf("wait %d\n", i);
}
if (i >= 100) return;
 
Возможно просто процесс был вытеснен и нужно больше ждать
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Ноябрь 30, 2013, 11:25 »

запускает 10 процессов и сканирует готовность в цикле.
Для чего это делать в цикле, когда QProcess умеет отсылать сигналы на каждый чих?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Ноябрь 30, 2013, 12:38 »

Для чего это делать в цикле, когда QProcess умеет отсылать сигналы на каждый чих?
Ах как Вы бдительны! Улыбающийся Я имел ввиду незачем делать 10 ниток только для запуска. Можно легко избежать как асинхронно, так и синхронно (что тоже неплохо) 
Записан
Базиля
Гость
« Ответ #4 : Ноябрь 30, 2013, 13:06 »

Благодарю за ответы!  Улыбающийся

Это несложно проверить утилитами ОС
Я через тесты удостоверился, что у каждого потока свой процесс.
В этом плане проблем нет.

Это само по себе нормально, и да, это невоспроизводимо при каждом запуске. Неясно зачем нужно 10 потоков, может лучше сделать все в одном, который запускает 10 процессов и сканирует готовность в цикле. Для начала можно попробовать так
Код
C++ (Qt)
int i;
for (i = 0; i < 100; ++i)
 if (process.waitForBytesWritten(time)) break;
 printf("wait %d\n", i);
}
if (i >= 100) return;
 
Возможно просто процесс был вытеснен и нужно больше ждать
10 потоков - потому что в дальнейшем будут разные процессы.
У каждого потока будет задача - запуск процесса, ввод данных, считывание ответа и все в том же духе.
Сейчас у меня идет тестирование модуля и для удобства я у меня все процессы одинаковые.

Насчет вытеснения процесса - идея хорошая, спасибо. Но в таком случае, таймер бы показал, что метод waitForBytesWritten (к примеру) превысил время выполнения в сравнении с переменной time. А мой лог показывает обратное - время выполнения в среднем не превышает и 100 мс. Когда в качестве параметра я передаю 2 секунды Грустный

Спасибо!
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Ноябрь 30, 2013, 13:29 »

Ах как Вы бдительны! Улыбающийся Я имел ввиду незачем делать 10 ниток только для запуска. Можно легко избежать как асинхронно, так и синхронно (что тоже неплохо)  
Если бы вы хотели сказать только это, то не привели бы этот бесполезный кусок кода. Подмигивающий
Ну да ладно.

В процессе тестирования блока, выводил значение времени исполнения данного блока (у меня есть таймер, который и замеряет время).
По времени исполнения, ни одно из условий не было истинным (т.е. ни одна из операций не превышала своего заданного времени выполнения).
Если возникает ошибка, то никто указанный интервал ждать не будет. Функция сразу завершиться. А вот почему происходят ошибки нужно разбираться. Причем странно, что ошибки могут возникать на разных этапах выполнения.
« Последнее редактирование: Ноябрь 30, 2013, 18:38 от Old » Записан
Базиля
Гость
« Ответ #6 : Ноябрь 30, 2013, 20:47 »

Если возникает ошибка, то никто указанный интервал ждать не будет. Функция сразу завершиться. А вот почему происходят ошибки нужно разбираться. Причем странно, что ошибки могут возникать на разных этапах выполнения.
Я просто лишний раз хотел сказать, что дело не в тайм ауте Улыбающийся
По поводу ошибки, кстати, самое интересное, что errorString() выводит "Unknown error".
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Ноябрь 30, 2013, 22:03 »

Я просто лишний раз хотел сказать, что дело не в тайм ауте Улыбающийся
Тогда нужно не время засекать, а пытаться понять, что происходит не так.

К примеру, в 7 потоках из 10, процессы завершились успешно, а вот предположим, что в 8 процессе, выполнилась ветка условия:
...
Или в 9 допустим :
...
Ну и в 10, предположим :
Что значит предположим/допустим? Эти ситуации происходят на самом деле или вы пытаетесь продумать, как нужно на них реагировать?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Декабрь 01, 2013, 10:58 »

Есть смысл заняться запускаемым - заменить его на что-то совсем простое типа "мама мыла раму" и откатать на нем
Записан
Базиля
Гость
« Ответ #9 : Декабрь 01, 2013, 19:45 »

Тогда нужно не время засекать, а пытаться понять, что происходит не так.
Я время засекал, чтобы убедиться, что проблема не в тайм ауте Улыбающийся

Что значит предположим/допустим? Эти ситуации происходят на самом деле или вы пытаетесь продумать, как нужно на них реагировать?
Эти ситуации происходят на самом деле, просто в хаотичном порядке.
Сейчас, предположим, если запустить - все процессы выполнятся удачно, а при следующем запуске - 2 из 10 пройдут по ветке одного из условий.

Есть смысл заняться запускаемым - заменить его на что-то совсем простое типа "мама мыла раму" и откатать на нем
А запускаемый процесс сейчас проще некуда - на вход подается число, а на выходе квадрат этого числа Улыбающийся

Сейчас решил немного упростить тестирование, используя только 1 поток - запускаю подряд 500 раз один и тот же процесс. Результаты такие же, на какой-нибудь из попыток запуска (каждый раз ее номер отличается) процесс проходит по ветке одного из условий.
То есть сам факт того, что один и тот же процесс не может быть выполнен одинаково 500 раз подряд меня вводит в заблуждение Грустный

Благодарю!
« Последнее редактирование: Декабрь 01, 2013, 19:48 от Базиля » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Декабрь 01, 2013, 19:55 »

Заинтриговали Улыбающийся Выкладывайте минимальные исходники, на неделе найду время и попытаюсь разобраться
Записан
Базиля
Гость
« Ответ #11 : Декабрь 01, 2013, 20:29 »

Спасибо! Улыбающийся
Если прямо в посте код скину, удобно будет?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Декабрь 01, 2013, 23:09 »

Спасибо! Улыбающийся
Если прямо в посте код скину, удобно будет?
Нет. Лучше архив со всеми файлами включая .pro.
Записан
Базиля
Гость
« Ответ #13 : Декабрь 02, 2013, 21:43 »

Вынес функцию отдельно, убрал логи - дабы не путать Улыбающийся

Заранее благодарю! Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Декабрь 02, 2013, 22:41 »

Вынес функцию отдельно, убрал логи - дабы не путать Улыбающийся
А что там в 1.exe? Похоже что дело в нем.

У меня нет венды, поэтому я заменил 1.exe на shell-скрипт, который читает из канала и записывает в канал 4.
Несколько раз запускал, всегда выполняется 1000 раз без ошибок.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.095 секунд. Запросов: 23.