如果子进程崩溃,QProcess ::是否已完成?

时间:2012-10-20 18:39:53

标签: c++ qt qprocess qt-signals

文档说如果子进程崩溃,将发出error()信号,但是finished()也会被发出,或者它只在成功退出时发出?

3 个答案:

答案 0 :(得分:6)

是。并返回状态,如docs状态:

void QProcess::finished ( int exitCode, QProcess::ExitStatus exitStatus ) [signal]

QProcess::NormalExit    0   The process exited normally.
QProcess::CrashExit 1   The process crashed.

答案 1 :(得分:2)

您可以通过测试找出答案。编写一个执行NULL指针取消引用的小程序(这将保证崩溃):

struct Foo {
    int a;
};

int main()
{
    Foo* foo = 0;
    int d = foo->a;
}

确保在没有优化的情况下构建,以便取消引用不会被优化。然后在QProcess中运行它并检查是否正在发出finished()

答案 2 :(得分:1)

正如其他人指出的那样,该问题的答案是“是”。

这对我来说就像一个问题,因为如果没有引用发出信号的对象,则必须执行以下操作:

void on_finished( int exitCode, QProcess::ExitStatus exitStatus )
{
    if ( existStatus == QProcess::CrashExit )
    {
        // We'll handle in on_errorOccured()
        return;
    }

    // ...
}


void on_errorOccured( QProcess::ProcessError error )
{
    // ...
}

作为接受选择的替代方法,我编写了一个精简包装器类,该类将(仅!)连接到QProcess::stateChanged(QProcess::ProcessState newState),并计算出使用newState并调用QProcess对象时发生的情况:

void ProcessWrapper::on_stateChanged(QProcess::ProcessState newState)
{
    switch (newState)
    {
    case QProcess::Starting:
        // No action needed
        break;
    case QProcess::Running:
        emit( started( this ) );
        break;
    case QProcess::NotRunning:
        if ( m_process.exitStatus() != QProcess::NormalExit )
            emit( crashed( this, m_process.error() ) );
        else
            emit( finished( this, m_process.exitCode() ) );
        break;
    }
}

包装器发出的信号具有两个属性:

  • 进程结束时仅发出一个信号,该信号告诉您如何结束(正常或异常)。
  • 每个信号都包括代码,该代码用于指示事情的进行方式和指向对象的指针,以便用户进一步查询。