【问题标题】:Terminating QProcess in a destructor在析构函数中终止 QProcess
【发布时间】:2018-10-14 19:18:34
【问题描述】:

试图阻止我的 QProcess 在它的父析构函数中时遇到问题。这是我的代码:

AbstractProcess::~AbstractProcess()
{
    if((m_process->state() == QProcess::Running)
       || (m_process->state() == QProcess::Starting))
    {
        m_process->terminate();
        m_process->waitForFinished();
    }
}

m_process 是指向QProcess 的指针。在AbstractProcess 的构造函数中我有这个代码:

 m_process = new QProcess(this);

所以,当AbstractProcess 被删除时,我得到了它的析构函数,并且在以下位置出现了分段错误:

m_process->waitForFinished();

谁能告诉我我的错误是什么?

UPD: 正如下面在 cmets 中所说,问题不在我提供的代码中。对此非常抱歉。因此,我将尝试解释问题所在。也许它会帮助某人。 AbstractProcess 正如您可能猜到的那样,它是一个抽象类。所以它有一些纯虚函数。其中有:

virtual void onProcessFinished(int exitCode, QProcess::ExitStatus
exitStatus) = 0;

我的构造函数的完整主体是:

m_process = new QProcess(this);
connect(m_process,static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
        this, &AbstractProcess::onProcessFinished);

现在很明显,在调用waitForFinished 时,进程会发出信号finished 并调用纯虚函数。这会导致未定义的行为。为了解决这个问题,我在停止我的进程之前打电话给disconnect。析构函数现在看起来像这样:

AbstractProcess::~AbstractProcess()
{
    disconnect(m_process,static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
               this, &AbstractProcess::onProcessFinished)        
    if((m_process->state() == QProcess::Running)
       || (m_process->state() == QProcess::Starting))
    {
        m_process->terminate();
        m_process->waitForFinished();
    }
}

感谢大家的帮助。

【问题讨论】:

  • 为什么在尝试终止该进程后需要调用m_process-&gt;waitForFinished();?不过,这不是wait for terminated
  • @vahancho 据我所知,在调用终止后,我必须调用 waitForFinished 以让进程完成它一直在做的所有工作。
  • @vahancho 任何程序都应该清理它启动的所有子进程,即操作系统的“等待”它。使用 waitForFinished 是在 Qt 应用程序中执行此操作的一种方法(只要您在事件循环挂起直到进程退出都可以的地方或时间执行此操作)。
  • @PolinaBodnar 您应该创建一个复制问题的 MCVE。据我所知(虽然我编写了类似的代码已经有一段时间了),问题不在于您显示的代码。您可能在某处有未定义的行为...
  • 我看不出所显示的代码有任何明显错误。如果可能的话,你能提供一个minimal reproducible example吗?

标签: qt qprocess


【解决方案1】:

当您首先调用m_process-&gt;terminate(); 时,不能保证进程会退出 .. 但不能保证进程会继续存在,因为调用(Windows 上的WM_CLOSE / Linux 上的SIGTERM)因此在可能已经终止的进程上调用m_process-&gt;waitForFinished(); 可能会导致分段错误。 正确且安全的方法是按顺序做正确的事情:

  m_process->waitForFinished();
  m_process->terminate();

【讨论】:

  • 抱歉,我很确定这是不正确的。即使子进程已经终止,QProcess 实例也会保持足够的状态,以便可以安全地调用 waitForFinished 等成员。
  • @G.M.好的,但是很高兴知道您确定的参考,因为我在文档中找不到它。
  • waitForFinished 检查进程的状态,如果状态为QProcess::NotRunning,则返回 false。 docs当进程退出时,QProcess 重新进入 NotRunning 状态(初始状态),并发出 finished()。 他们还说 waitForFinished如果过程完成;否则返回 false(如果操作超时、发生错误或此 QProcess 已完成)。
  • 嗯。 waitForFinished 阻塞直到进程终止,所以从不调用终止,所以它会无限期地等待...... IOW 主应用程序将挂起。
  • 别担心,这已经被 Qt 开发者考虑在内了。如果你在它进入Running 状态之前杀死它,它甚至是lets the process emit started/errorOccurred
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多