Название: Убийство процесса. Отправлено: FreshMeat от Март 13, 2017, 09:46 Доброго времени суток!
Возникла следующая проблема: я писал фронтенд с графическим интерфейсом к консольному приложению. Помимо всего прочего, при закрытии он должен был убивать запущенный процесс консольного приложения, которое имеет свойство работать долго и использовать много ресурсов компьютера. Выглядит это так:
Из всех попыток что-то изменить удалась только одна - поместить во второй класс глобальную переменную типа 'QProcess', в функции вызова вместо создания нового 'QProcess' сразу стартовать строку из глобального, в слот 'Kill()' сразу вызывать 'process.kill()'. Да, консольное приложение в этом случае закрывается, но при каждом новом вызове 'process.start(line)' выводится предупреждение вида: QObject: Cannot create children for a parent that is in a different thread. (Parent is QProcess(0x5f9698), parent's thread is QThread(0xb037738), current thread is QThread(0xdad7780) Вопрос - как же всё-таки грамотно реализовать убиение процесса? Название: Re: Убийство процесса. Отправлено: Пантер от Март 13, 2017, 09:59 Ты некорректно работаешь с процессом. Отдельный поток вообще не нужен. Вешайся на сигнал QProcess::readyReadStandardOutput и в слоте читай данные.
Название: Re: Убийство процесса. Отправлено: FreshMeat от Март 13, 2017, 14:28 Цитировать Ты некорректно работаешь с процессом. Отдельный поток вообще не нужен. Я его и не создаю, вроде как. Вот код той функции.Код: void MyClass::Run(QString line) Цитировать Вешайся на сигнал QProcess::readyReadStandardOutput и в слоте читай данные. Звучит как хорошая идея, но тогда как добиться ожидания конца работы? Через QEventLoop?Название: Re: Убийство процесса. Отправлено: qate от Март 13, 2017, 14:35 Звучит как хорошая идея, но тогда как добиться ожидания конца работы? Через QEventLoop? при окончании работы qprocess выкинет сигнал Название: Re: Убийство процесса. Отправлено: Пантер от Март 13, 2017, 14:38 FreshMeat, используй асинхронную работу с QProcess через сигналы/слоты.
Название: Re: Убийство процесса. Отправлено: FreshMeat от Март 13, 2017, 16:39 при окончании работы qprocess выкинет сигнал Который сам по себе не тормозит выполнение остальной части кода. Или я не прав?FreshMeat, используй асинхронную работу с QProcess через сигналы/слоты. Уже пытаюсь организовать. Читая документацию Qt, узнал, что сигналы с сигналами можно коннектить, что упростило часть задачи. Теперь вот гадаю, как законнектить сигнал процесса на готовность чтения с сигналом второго класса на отправку строки вида 'SendLine(QString)', ведь нужно как-то указать, что отправить нужно именно содержимое выходного канала, а не просто QString.Грубо говоря, на ум сразу напрашивается нечто подобное: Код: connect(&process,SIGNAL(readyReadStandartError()),this,SIGNAL(SendLine(QString))); Название: Re: Убийство процесса. Отправлено: FreshMeat от Март 13, 2017, 17:30 В общем, соединив сигнал главного окна 'Kill()' с сигналом второго класса 'Kill()', а тот в свою очередь со слотом процесса 'kill()', я добился того, чего хотел - процесс теперь исправно закрывается с закрытием главного окна. Всем спасибо, все свободны.
Напоследок уточню - удалив первый пост, я удалю только его или всю тему? Название: Re: Убийство процесса. Отправлено: Пантер от Март 14, 2017, 07:54 Не удаляй, вдруг, кому-то еще понадобится. А по поводу сигнала, сделай промежуточный слот, в котором вычитаешь данные и заэммитишь сигнал с ними.
Название: Re: Убийство процесса. Отправлено: FreshMeat от Март 14, 2017, 09:16 Не удаляй, вдруг, кому-то еще понадобится. Хорошо, не буду.Цитировать А по поводу сигнала, сделай промежуточный слот, в котором вычитаешь данные и заэммитишь сигнал с ними. Я сделал бы, если бы знал, как правильно взаимодействовать с 'sender()'-ом, ибо сигнал 'readyRead()' сам по себе ничего не отправляет. Его, наверное, можно было бы перегрузить ручками, но зачем, если циклическое чтение полностью удовлетворяет мои требования для данной задачи? Тут просто суть в том, что мне не нужна асинхронная работа процесса и объекта класса, его вызывающего, они должны выполняться по очереди, друг за другом. А раз так, к чему организовывать слот-сигнальные взаимодействия процесса и класса по отслеживанию завершения, готовности, когда можно просто пустить их в одном потоке, но отдельном от главного окна?Впрочем, послушаю любой совет, как это дело облагородить. Название: Re: Убийство процесса. Отправлено: Пантер от Март 14, 2017, 13:00 Отдельный поток тебе не нужен, я уже говорил об этом. Смотри пример. Создай класс ProcessCommunicator, в котором инкапсулируй QProcess, а наружу прокинь сигнал newLineAvailable(const QString &line). Это как вариант.
|