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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [QProcess] После terminate(), либо kill(), ProcessState возвращает Running  (Прочитано 8930 раз)
CerJo
Гость
« : Апрель 23, 2014, 13:07 »

Всем привет!

Имеется система, в которой по нажатию кнопки основное приложение запускает дочернее. Эта же кнопка должна сие приложение закрывать.
После нажатия, приложение запускается. При повторном нажатии - закрывается. Но если снова нажать на кнопку, ничего не происходит.

Основная программа запускает дочернюю:
Код:
QProcess proc;
proc.start(prog, params);
В некоторый момент времени вызывается terminate() (с kill() тоже пробовалось):
Код:
proc.terminate();
//proc.kill();
1) Сигнал finished() не приходит.
2) При вызове state(), возвращается Running:
Код:
if (proc.state == QProcess::Running)
    QMessageBox::critical(this, "", "Running");
// Выводит Running
Но при этом процесс завершается (точнее пропадает окно; проверить, висит ли процесс в системе, не представляется возможным).

В связи с этим (как я понимаю), при повторном вызове proc.start, ничего не происходит.

Подскажите, пожалуйста, что я делаю не так, или где я ошибаюсь. Заранее спасибо!

P. S. Предположил, что время между terminate() и state() мало, но даже после 5 минут ожидания возвращается Running.
Записан
Bepec
Гость
« Ответ #1 : Апрель 23, 2014, 15:23 »

А давайте пофантазируем и представим ваш код. В нём может быть ошибка? Наверное ошибка именно в нём!
Записан
CerJo
Гость
« Ответ #2 : Апрель 24, 2014, 07:35 »

Привожу код приложения

h-файл:
Код:
namespace Ui {
class Controlpanel;
}

class Controlpanel : public QWidget
{
    Q_OBJECT
    
public:
    explicit Controlpanel(QWidget *parent = 0);
    ~Controlpanel();
    QProcess proc;

public slots:
    void readOut();
    void exitProc(int, QProcess::ExitStatus);

private:
    Ui::Controlpanel *ui;
    void init();

protected:
    bool eventFilter(QObject * ,QEvent * );

};

cpp файл:
Код:
Controlpanel::Controlpanel(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Controlpanel)
{
    ui->setupUi(this);
    init();
}

void Controlpanel::init()
{
    this->installEventFilter(this);
    connect(&proc,SIGNAL(readyReadStandardOutput()),this,SLOT(readOut()));
    connect(&proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(exitProc(int,QProcess::ExitStatus)));
}

bool Controlpanel::eventFilter(QObject *obj, QEvent *event)
{
        if( event->type() == QEvent::KeyPress)
           {
                QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
                switch (keyEvent->key()) {
                case 48: // "0"
   if (proc.state() == QProcess::NotRunning)
QMessageBox::critical(this, "" , "NOT RUNNING!");
   if (proc.state() == QProcess::Running)
QMessageBox::critical(this,"","RUNNING!");
   if (proc.state() == QProcess::Starting)
QMessageBox::critical(this, "", "STARTING!");
   
                    if (proc.state() != QProcess::Running) {
                        proc.start("/home/steerage/Steerage", QStringList() << "-qt3");
                 QMessageBox::critical(this,"","Starting");
   } else
    if (proc.state() == QProcess::Running) {
                            proc.terminate();
                            //proc.kill();
   QMessageBox::critical(this,"","Terminating");
}
   break;
default:
                    break;
                }
           }
        return QObject::eventFilter(obj, event);
}

void Controlpanel::readOut()
{
    QByteArray arr;
    arr = proc.readAllStandardOutput();
    if ((QChar(arr[0]) == QChar('4')) && (QChar(arr[1]) == QChar('8')))
proc.terminate();
        //proc.kill();
    else
QMessageBox::critical(this,"",QString(arr));
}

void Controlpanel::exitProc(int exCode, QProcess::ExitStatus exStat) {
    QMessageBox::critical(this, "", "The process was finished");
}


Сообщение "The process was finished" не приходит никогда.
Когда основное приложение из стандартного потока вывода дочернего приложения читает код "48", приложение закрывается, но proc.state возвращает running.

Код:
if (proc.state() != QProcess::Running) {
                        proc.start("/home/steerage/Steerage", QStringList() << "-qt3");
                 QMessageBox::critical(this,"","Starting");
   }
Условие (proc.state() != QProcess::Running) убирал, последующий terminate() комментировал, выводится сообщение "Starting", но приложение не запускается повторно.
« Последнее редактирование: Апрель 24, 2014, 07:42 от CerJo » Записан
Bepec
Гость
« Ответ #3 : Апрель 24, 2014, 11:13 »

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

Проблема в вашем втором приложении. Видимо ошибка там, ибо у меня всё спокойно отрабатывает без излишеств.
Выкладывайте код второго, или же скиньте его.
« Последнее редактирование: Апрель 24, 2014, 11:29 от Bepec » Записан
OKTA
Гость
« Ответ #4 : Апрель 24, 2014, 11:39 »

Если слать terminate(), то это необязательно приведет к завершению процесса, как сказано в доках и как получается на практике.
Я пробовал на винде с calc.exe. Посылается terminate() и убивается само окошко калькулятора, а в процессах продолжает сидеть и сигнал о завершении приходит если вручную его убить в диспетчере. Если пользоваться kill(), то убивается на ура и смертельно, сигнал приходит сразу.
На линуксе такое поведение, как у вас, может быть из-за того, что приложение, запускаемое через QProcess, внутри себя запускает еще что-нибудь и из-за этого нет сигнала о завершении процесса и т.д. Попробовать к сожалению сейчас не могу.

P.S. Если в винде запускать через QProcess explorer.exe, то сигнал о завершении приходит сразу же, не смотря на то, что ты таких попыток не делал))) Но окошко эксплорера продолжает жить своей жизнью - видимо винда перехватывает процесс.
Записан
Bepec
Гость
« Ответ #5 : Апрель 24, 2014, 11:48 »

В винде explorer при запуске себя лишь посылает главному эксплореру сигнал форкнуться и сразу завершается Улыбающийся И уже главный эксплорер форкает самого себя Улыбающийся

Записан
OKTA
Гость
« Ответ #6 : Апрель 24, 2014, 11:58 »

А вот notepad.exe при terminate() сразу же завершается в отличии от calc.exe.
Шайтан-Винда  Смеющийся
Записан
CerJo
Гость
« Ответ #7 : Апрель 28, 2014, 10:05 »

Спасибо за ответы. Временами программа срабатывает, временами нет. К сожалению, выложить код запускаемого процесса не могу - нет исходников.
И terminate() и kill() работают через раз. Т. е. сегодня всё работает, завтра опять приложение не запускается повторно. Грешу на операционку (Эльбрус).

Такой вопрос: а что, если объект QProcess сделать динамичным и после kill(), либо terminate() дестроить его, заново запускать конструктор и коннектить. Как я понимаю, это решит только симптомы проблемы, скорей всего будут клониться приложения? Или стоит попробовать?

P.S. Попробовал запустить приложение не через QProcess, а руками: при завершении его в консоль приходит сообщение Illegal Instruction. Думаю, это и создаёт проблему.
Записан
OKTA
Гость
« Ответ #8 : Апрель 28, 2014, 10:32 »

Ну да, будешь плодить приложение, если оно не будет успешно завершаться. Попробуй системный kill - если что будешь запоминать pid процесса и добивать его, если QProcess сам не сможет.
Записан
Bepec
Гость
« Ответ #9 : Апрель 28, 2014, 11:05 »

Вы с приложением руками поработайте. Проблема в нём скорее всего. А Эльбрус насколько я помню тот же linux.
Записан
OKTA
Гость
« Ответ #10 : Апрель 28, 2014, 11:13 »

Цитировать
К сожалению, выложить код запускаемого процесса не могу - нет исходников.

Видать не получится поработать.
Записан
CerJo
Гость
« Ответ #11 : Апрель 29, 2014, 13:21 »

Удалось получить картину висящих процессов в системе. На картинке приведён скрин "до" kill() и "после" kill(). Похоже на процесс-зомби. Кто-нибудь знает, как можно это исправить?
Записан
CerJo
Гость
« Ответ #12 : Май 05, 2014, 15:17 »

Решил проблему, запустив программу с правами суперпользователя.

Всем спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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