【问题标题】:Is QProcess::finished emitted if the child process crashes?如果子进程崩溃,是否会发出 QProcess::finished?
【发布时间】:2012-10-20 18:39:52
【问题描述】:

文档说error() 信号会在子进程崩溃时发出,但finished() 也会发出还是仅在成功退出时发出?

【问题讨论】:

    标签: c++ qt qprocess qt-signals


    【解决方案1】:

    是的。它会返回您的状态,如docs 状态:

    void QProcess::finished ( int exitCode, QProcess::ExitStatus exitStatus ) [signal]
    
    QProcess::NormalExit    0   The process exited normally.
    QProcess::CrashExit 1   The process crashed.
    

    【讨论】:

      【解决方案2】:

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

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

      确保您在构建时不进行优化,以免取消引用得到优化。然后在 QProcess 中运行它并检查是否正在发出 finished()

      【讨论】:

      • 没有。这不是真的。 Qt 是跨平台库。如果它在特定系统上以某种方式工作,并不意味着它在其他系统上也能正常工作。
      • @Lol4t0 我不确定您所说的“不正确”是什么意思。毫无疑问,该测试将清楚地表明 QProcess 是否发出信号。在您的回答中,您找到了清除它的实际文档。在这里,我只是提供了一种获取一些经验证据的方法。当然假设是,如果信号是在 OP 的平台上发出的,那么对于所有受支持的平台也是如此。虽然假设不是那么好,所以显然你的答案是更好的:)
      • 假设首先是错误的,因为QProcess 是 Qt platfromdependednt 的一部分。你说'你可以通过测试来发现'。但实际上你不能。你只能假设
      【解决方案3】:

      正如其他人所说,这个问题的答案是“是的”。

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

      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;
          }
      }
      

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

      • 当进程结束时,只会发出一个信号,而哪个信号会告诉您它是如何结束的(正常或异常)。
      • 每个信号都包含一个代码,用于说明事情是如何进行的和一个指向对象的指针,以便用户可以进一步查询。

      【讨论】:

        猜你喜欢
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-20
        • 1970-01-01
        • 2016-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多